summaryrefslogtreecommitdiff
path: root/source/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins')
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp46
-rw-r--r--source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h4
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp218
-rw-r--r--source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h4
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp35
-rw-r--r--source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp86
-rw-r--r--source/Plugins/ABI/SysV-arm/ABISysV_arm.h4
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp73
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h4
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp11
-rw-r--r--source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h4
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp57
-rw-r--r--source/Plugins/ABI/SysV-i386/ABISysV_i386.h4
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp21
-rw-r--r--source/Plugins/ABI/SysV-mips/ABISysV_mips.h4
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp68
-rw-r--r--source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp94
-rw-r--r--source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h4
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp62
-rw-r--r--source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h4
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp56
-rw-r--r--source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h8
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp87
-rw-r--r--source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h4
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.cpp30
-rw-r--r--source/Plugins/Architecture/Arm/ArchitectureArm.h6
-rw-r--r--source/Plugins/Architecture/CMakeLists.txt1
-rw-r--r--source/Plugins/Architecture/Mips/ArchitectureMips.cpp241
-rw-r--r--source/Plugins/Architecture/Mips/ArchitectureMips.h52
-rw-r--r--source/Plugins/Architecture/Mips/CMakeLists.txt10
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp123
-rw-r--r--source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h16
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp97
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h6
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp18
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h4
-rw-r--r--source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h5
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp47
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h6
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp47
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h13
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp19
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h8
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp2
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h3
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp16
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h3
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp14
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h4
-rw-r--r--source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h4
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp36
-rw-r--r--source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h4
-rw-r--r--source/Plugins/ExpressionParser/CMakeLists.txt1
-rw-r--r--source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp3
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp54
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h10
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h4
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp352
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h38
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h4
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp6
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h4
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangHost.cpp13
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp9
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h4
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp146
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUserExpression.h18
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp2
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h4
-rw-r--r--source/Plugins/ExpressionParser/Clang/IRForTarget.cpp42
-rw-r--r--source/Plugins/ExpressionParser/Go/CMakeLists.txt13
-rw-r--r--source/Plugins/ExpressionParser/Go/GoAST.h1977
-rw-r--r--source/Plugins/ExpressionParser/Go/GoLexer.cpp350
-rw-r--r--source/Plugins/ExpressionParser/Go/GoLexer.h181
-rw-r--r--source/Plugins/ExpressionParser/Go/GoParser.cpp886
-rw-r--r--source/Plugins/ExpressionParser/Go/GoParser.h145
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.cpp668
-rw-r--r--source/Plugins/ExpressionParser/Go/GoUserExpression.h94
-rw-r--r--source/Plugins/ExpressionParser/Go/gen_go_ast.py464
-rw-r--r--source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp96
-rw-r--r--source/Plugins/Instruction/ARM/EmulationStateARM.cpp4
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp18
-rw-r--r--source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h4
-rw-r--r--source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp137
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp130
-rw-r--r--source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h4
-rw-r--r--source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h4
-rw-r--r--source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h4
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h4
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp8
-rw-r--r--source/Plugins/JITLoader/GDB/JITLoaderGDB.h4
-rw-r--r--source/Plugins/Language/CMakeLists.txt4
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp6
-rw-r--r--source/Plugins/Language/CPlusPlus/CMakeLists.txt5
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp216
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h11
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h4
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp186
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.h31
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp19
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp15
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp4
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp4
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp85
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp4
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp256
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVariant.h31
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp38
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcpp.cpp11
-rw-r--r--source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp99
-rw-r--r--source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h51
-rw-r--r--source/Plugins/Language/ClangCommon/CMakeLists.txt9
-rw-r--r--source/Plugins/Language/ClangCommon/ClangHighlighter.cpp237
-rw-r--r--source/Plugins/Language/ClangCommon/ClangHighlighter.h38
-rw-r--r--source/Plugins/Language/Go/CMakeLists.txt13
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.cpp152
-rw-r--r--source/Plugins/Language/Go/GoFormatterFunctions.h43
-rw-r--r--source/Plugins/Language/Go/GoLanguage.cpp127
-rw-r--r--source/Plugins/Language/Go/GoLanguage.h63
-rw-r--r--source/Plugins/Language/Java/CMakeLists.txt12
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.cpp167
-rw-r--r--source/Plugins/Language/Java/JavaFormatterFunctions.h35
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.cpp101
-rw-r--r--source/Plugins/Language/Java/JavaLanguage.h52
-rw-r--r--source/Plugins/Language/OCaml/CMakeLists.txt12
-rw-r--r--source/Plugins/Language/OCaml/OCamlLanguage.cpp63
-rw-r--r--source/Plugins/Language/OCaml/OCamlLanguage.h51
-rw-r--r--source/Plugins/Language/ObjC/CF.cpp2
-rw-r--r--source/Plugins/Language/ObjC/CMakeLists.txt1
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.cpp67
-rw-r--r--source/Plugins/Language/ObjC/NSArray.cpp31
-rw-r--r--source/Plugins/Language/ObjC/NSDictionary.cpp4
-rw-r--r--source/Plugins/Language/ObjC/NSError.cpp4
-rw-r--r--source/Plugins/Language/ObjC/NSException.cpp158
-rw-r--r--source/Plugins/Language/ObjC/NSIndexPath.cpp10
-rw-r--r--source/Plugins/Language/ObjC/NSSet.cpp4
-rw-r--r--source/Plugins/Language/ObjC/NSString.cpp13
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.cpp20
-rw-r--r--source/Plugins/Language/ObjC/ObjCLanguage.h11
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt3
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp9
-rw-r--r--source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h11
-rw-r--r--source/Plugins/LanguageRuntime/CMakeLists.txt2
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp188
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h7
-rw-r--r--source/Plugins/LanguageRuntime/Go/CMakeLists.txt2
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp215
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h86
-rw-r--r--source/Plugins/LanguageRuntime/Java/CMakeLists.txt10
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp157
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h78
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp15
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp2
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp124
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h12
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp9
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp94
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp8
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h4
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp15
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h4
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp4
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h4
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp82
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h10
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp4
-rw-r--r--source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h4
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp9
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h3
-rw-r--r--source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h6
-rw-r--r--source/Plugins/ObjectFile/Breakpad/CMakeLists.txt11
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp315
-rw-r--r--source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h109
-rw-r--r--source/Plugins/ObjectFile/CMakeLists.txt3
-rw-r--r--source/Plugins/ObjectFile/ELF/ELFHeader.cpp29
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp735
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h28
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp16
-rw-r--r--source/Plugins/ObjectFile/JIT/ObjectFileJIT.h8
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp435
-rw-r--r--source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h21
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp441
-rw-r--r--source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h19
-rw-r--r--source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp2
-rw-r--r--source/Plugins/OperatingSystem/CMakeLists.txt1
-rw-r--r--source/Plugins/OperatingSystem/Go/CMakeLists.txt10
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp498
-rw-r--r--source/Plugins/OperatingSystem/Go/OperatingSystemGo.h90
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp10
-rw-r--r--source/Plugins/OperatingSystem/Python/OperatingSystemPython.h4
-rw-r--r--source/Plugins/Platform/Android/AdbClient.cpp3
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp12
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h4
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp1
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h4
-rw-r--r--source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp14
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.cpp5
-rw-r--r--source/Plugins/Platform/Kalimba/PlatformKalimba.h4
-rw-r--r--source/Plugins/Platform/Linux/PlatformLinux.cpp16
-rw-r--r--source/Plugins/Platform/MacOSX/CMakeLists.txt1
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp9
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp37
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp37
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.cpp131
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwin.h21
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp127
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h31
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp23
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformMacOSX.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp186
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h73
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp6
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp6
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp99
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h12
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp8
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h4
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp37
-rw-r--r--source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h4
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h4
-rw-r--r--source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm4
-rw-r--r--source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp16
-rw-r--r--source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp8
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp39
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h4
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.cpp32
-rw-r--r--source/Plugins/Platform/Windows/PlatformWindows.h4
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp21
-rw-r--r--source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h4
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.cpp13
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h1
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp8
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.h2
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp31
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp7
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.h3
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h3
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp2
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp325
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h16
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp2
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp2
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp5
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp5
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp2
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp2
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp2
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp2
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp24
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h8
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp22
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h5
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h4
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp4
-rw-r--r--source/Plugins/Process/NetBSD/CMakeLists.txt1
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp128
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h15
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp2
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp4
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIXLog.h4
-rw-r--r--source/Plugins/Process/Utility/ARMUtils.h2
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt1
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp4
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.h4
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.cpp4
-rw-r--r--source/Plugins/Process/Utility/FreeBSDSignals.h1
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.cpp3
-rw-r--r--source/Plugins/Process/Utility/GDBRemoteSignals.h4
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h8
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h4
-rw-r--r--source/Plugins/Process/Utility/LinuxProcMaps.cpp113
-rw-r--r--source/Plugins/Process/Utility/LinuxProcMaps.h28
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.cpp3
-rw-r--r--source/Plugins/Process/Utility/LinuxSignals.h4
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.cpp3
-rw-r--r--source/Plugins/Process/Utility/MipsLinuxSignals.h4
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.cpp4
-rw-r--r--source/Plugins/Process/Utility/NetBSDSignals.h1
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp9
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp21
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp10
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_i386.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDummy.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.cpp2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp180
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.h11
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp8
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMemory.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp6
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextThreadMemory.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_arm64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h1
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_mips64.h4
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_ppc64.h1
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_ppc64le.h1
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_s390x.h4
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp57
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.h4
-rw-r--r--source/Plugins/Process/Utility/ThreadMemory.h4
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.cpp23
-rw-r--r--source/Plugins/Process/Utility/UnwindLLDB.h4
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp4
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h4
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp16
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.h2
-rw-r--r--source/Plugins/Process/Windows/Common/ForwardDecl.h2
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp104
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h4
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp7
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp2
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp14
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp2
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp59
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h10
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp212
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h98
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp57
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp143
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h156
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp204
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h83
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp3
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp51
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp18
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp18
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp12
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h4
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp215
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h12
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h4
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp13
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.h4
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp78
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h4
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp4
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.h4
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.cpp354
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h24
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.cpp4
-rw-r--r--source/Plugins/Process/minidump/MinidumpTypes.h65
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.cpp334
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h14
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp532
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h93
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp834
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h83
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp2
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h2
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp2
-rw-r--r--source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h2
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.cpp28
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.h4
-rw-r--r--source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h4
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp11
-rw-r--r--source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h4
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp177
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h45
-rw-r--r--source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp42
-rw-r--r--source/Plugins/SymbolFile/Breakpad/CMakeLists.txt12
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp223
-rw-r--r--source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h146
-rw-r--r--source/Plugins/SymbolFile/CMakeLists.txt2
-rw-r--r--source/Plugins/SymbolFile/DWARF/CMakeLists.txt3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParser.h12
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp308
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h37
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp772
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h84
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp510
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h81
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp210
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h59
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp6
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h17
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFAttribute.h11
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp31
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDIE.h5
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h1
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp140
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h28
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp146
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h18
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp178
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h46
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFDefines.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp248
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFFormValue.h8
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp108
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFUnit.h11
-rw-r--r--source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp10
-rw-r--r--source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp397
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h96
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp182
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h55
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp39
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h10
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp9
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h4
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp4
-rw-r--r--source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h4
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CMakeLists.txt21
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp217
-rw-r--r--source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h95
-rw-r--r--source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp673
-rw-r--r--source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h42
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp1348
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h144
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp200
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbIndex.h162
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp161
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbSymUid.h126
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp750
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbUtil.h159
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp1571
-rw-r--r--source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h245
-rw-r--r--source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp191
-rw-r--r--source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h75
-rw-r--r--source/Plugins/SymbolFile/PDB/CMakeLists.txt1
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.cpp1005
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBASTParser.h67
-rw-r--r--source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp658
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp591
-rw-r--r--source/Plugins/SymbolFile/PDB/SymbolFilePDB.h69
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp38
-rw-r--r--source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h33
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp9
-rw-r--r--source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h4
-rw-r--r--source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp26
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp7
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h4
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp7
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h4
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp7
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h4
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp7
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h4
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp9
-rw-r--r--source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h3
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp2
-rw-r--r--source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h6
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp8
-rw-r--r--source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h4
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp344
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h7
525 files changed, 19647 insertions, 14855 deletions
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
index e0e293d7ae68..9055660f2d6c 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
@@ -9,19 +9,13 @@
#include "ABIMacOSX_arm.h"
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -30,6 +24,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Utility/ARMDefines.h"
@@ -1327,16 +1323,13 @@ size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
ABISP
ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type == llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABIMacOSX_arm(process_sp));
- return g_abi_sp;
+ return ABISP(new ABIMacOSX_arm(process_sp));
}
}
@@ -1477,14 +1470,16 @@ bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
if (compiler_type) {
bool is_signed = false;
size_t bit_width = 0;
- if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = compiler_type.GetBitSize(&thread);
- } else if (compiler_type.IsPointerOrReferenceType()) {
- bit_width = compiler_type.GetBitSize(&thread);
- } else {
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed))
+ bit_width = *bit_size;
+ else if (compiler_type.IsPointerOrReferenceType())
+ bit_width = *bit_size;
+ else
// We only handle integer, pointer and reference types currently...
return false;
- }
if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
if (value_idx < 4) {
@@ -1581,9 +1576,11 @@ ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- size_t bit_width = compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
+ if (!bit_width)
+ return return_valobj_sp;
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 128:
@@ -1599,14 +1596,17 @@ ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
const RegisterInfo *r3_reg_info =
reg_ctx->GetRegisterInfoByName("r3", 0);
if (r1_reg_info && r2_reg_info && r3_reg_info) {
- const size_t byte_size = compiler_type.GetByteSize(&thread);
+ llvm::Optional<uint64_t> byte_size =
+ compiler_type.GetByteSize(&thread);
+ if (!byte_size)
+ return return_valobj_sp;
ProcessSP process_sp(thread.GetProcess());
- if (byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
- r2_reg_info->byte_size +
- r3_reg_info->byte_size &&
+ if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
+ r2_reg_info->byte_size +
+ r3_reg_info->byte_size &&
process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue r0_reg_value;
RegisterValue r1_reg_value;
diff --git a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
index d3c20e1e618f..94f1e31a1235 100644
--- a/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
+++ b/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABIMacOSX_arm_h_
#define liblldb_ABIMacOSX_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
index 85f864ec7561..d8706c4a9cdd 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
@@ -9,18 +9,13 @@
#include "ABIMacOSX_arm64.h"
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -30,6 +25,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "Utility/ARM64_DWARF_Registers.h"
@@ -1667,15 +1664,12 @@ size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; }
ABISP
ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type == llvm::Triple::Apple) {
if (arch_type == llvm::Triple::aarch64) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABIMacOSX_arm64(process_sp));
- return g_abi_sp;
+ return ABISP(new ABIMacOSX_arm64(process_sp));
}
}
@@ -1768,90 +1762,92 @@ bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread,
return false;
CompilerType value_type = value->GetCompilerType();
- if (value_type) {
- bool is_signed = false;
- size_t bit_width = 0;
- if (value_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = value_type.GetBitSize(&thread);
- } else if (value_type.IsPointerOrReferenceType()) {
- bit_width = value_type.GetBitSize(&thread);
- } else {
- // We only handle integer, pointer and reference types currently...
- return false;
- }
+ llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
- if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
- if (value_idx < 8) {
- // Arguments 1-6 are in x0-x5...
- const RegisterInfo *reg_info = nullptr;
- // Search by generic ID first, then fall back to by name
- uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
- if (arg_reg_num != LLDB_INVALID_REGNUM) {
- reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
- } else {
- switch (value_idx) {
- case 0:
- reg_info = reg_ctx->GetRegisterInfoByName("x0");
- break;
- case 1:
- reg_info = reg_ctx->GetRegisterInfoByName("x1");
- break;
- case 2:
- reg_info = reg_ctx->GetRegisterInfoByName("x2");
- break;
- case 3:
- reg_info = reg_ctx->GetRegisterInfoByName("x3");
- break;
- case 4:
- reg_info = reg_ctx->GetRegisterInfoByName("x4");
- break;
- case 5:
- reg_info = reg_ctx->GetRegisterInfoByName("x5");
- break;
- case 6:
- reg_info = reg_ctx->GetRegisterInfoByName("x6");
- break;
- case 7:
- reg_info = reg_ctx->GetRegisterInfoByName("x7");
- break;
- }
+ bool is_signed = false;
+ size_t bit_width = 0;
+ if (value_type.IsIntegerOrEnumerationType(is_signed)) {
+ bit_width = *bit_size;
+ } else if (value_type.IsPointerOrReferenceType()) {
+ bit_width = *bit_size;
+ } else {
+ // We only handle integer, pointer and reference types currently...
+ return false;
+ }
+
+ if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
+ if (value_idx < 8) {
+ // Arguments 1-6 are in x0-x5...
+ const RegisterInfo *reg_info = nullptr;
+ // Search by generic ID first, then fall back to by name
+ uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
+ if (arg_reg_num != LLDB_INVALID_REGNUM) {
+ reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
+ } else {
+ switch (value_idx) {
+ case 0:
+ reg_info = reg_ctx->GetRegisterInfoByName("x0");
+ break;
+ case 1:
+ reg_info = reg_ctx->GetRegisterInfoByName("x1");
+ break;
+ case 2:
+ reg_info = reg_ctx->GetRegisterInfoByName("x2");
+ break;
+ case 3:
+ reg_info = reg_ctx->GetRegisterInfoByName("x3");
+ break;
+ case 4:
+ reg_info = reg_ctx->GetRegisterInfoByName("x4");
+ break;
+ case 5:
+ reg_info = reg_ctx->GetRegisterInfoByName("x5");
+ break;
+ case 6:
+ reg_info = reg_ctx->GetRegisterInfoByName("x6");
+ break;
+ case 7:
+ reg_info = reg_ctx->GetRegisterInfoByName("x7");
+ break;
}
+ }
- if (reg_info) {
- RegisterValue reg_value;
+ if (reg_info) {
+ RegisterValue reg_value;
- if (reg_ctx->ReadRegister(reg_info, reg_value)) {
- if (is_signed)
- reg_value.SignExtend(bit_width);
- if (!reg_value.GetScalarValue(value->GetScalar()))
- return false;
- continue;
- }
- }
- return false;
- } else {
- if (sp == 0) {
- // Read the stack pointer if we already haven't read it
- sp = reg_ctx->GetSP(0);
- if (sp == 0)
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ if (is_signed)
+ reg_value.SignExtend(bit_width);
+ if (!reg_value.GetScalarValue(value->GetScalar()))
return false;
+ continue;
}
-
- // Arguments 5 on up are on the stack
- const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
- Status error;
- if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
- sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ }
+ return false;
+ } else {
+ if (sp == 0) {
+ // Read the stack pointer if we already haven't read it
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
return false;
+ }
- sp += arg_byte_size;
- // Align up to the next 8 byte boundary if needed
- if (sp % 8) {
- sp >>= 3;
- sp += 1;
- sp <<= 3;
- }
+ // Arguments 5 on up are on the stack
+ const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
+ Status error;
+ if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
+ sp, arg_byte_size, is_signed, value->GetScalar(), error))
+ return false;
+
+ sp += arg_byte_size;
+ // Align up to the next 8 byte boundary if needed
+ if (sp % 8) {
+ sp >>= 3;
+ sp += 1;
+ sp <<= 3;
}
}
}
@@ -2115,13 +2111,12 @@ static bool LoadValueFromConsecutiveGPRRegisters(
uint32_t &NGRN, // NGRN (see ABI documentation)
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data) {
- const size_t byte_size = value_type.GetByteSize(nullptr);
-
- if (byte_size == 0)
+ llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
+ if (!byte_size || *byte_size == 0)
return false;
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
Status error;
@@ -2133,7 +2128,9 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
if (!base_type)
return false;
- const size_t base_byte_size = base_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ if (!base_byte_size)
+ return false;
uint32_t data_offset = 0;
for (uint32_t i = 0; i < homogeneous_count; ++i) {
@@ -2144,7 +2141,7 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (reg_info == nullptr)
return false;
- if (base_byte_size > reg_info->byte_size)
+ if (*base_byte_size > reg_info->byte_size)
return false;
RegisterValue reg_value;
@@ -2153,11 +2150,11 @@ static bool LoadValueFromConsecutiveGPRRegisters(
return false;
// Make sure we have enough room in "heap_data_ap"
- if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize()) {
+ if ((data_offset + *base_byte_size) <= heap_data_ap->GetByteSize()) {
const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_ap->GetBytes() + data_offset, base_byte_size,
+ reg_info, heap_data_ap->GetBytes() + data_offset, *base_byte_size,
byte_order, error);
- if (bytes_copied != base_byte_size)
+ if (bytes_copied != *base_byte_size)
return false;
data_offset += bytes_copied;
++NSRN;
@@ -2172,10 +2169,10 @@ static bool LoadValueFromConsecutiveGPRRegisters(
}
const size_t max_reg_byte_size = 16;
- if (byte_size <= max_reg_byte_size) {
- size_t bytes_left = byte_size;
+ if (*byte_size <= max_reg_byte_size) {
+ size_t bytes_left = *byte_size;
uint32_t data_offset = 0;
- while (data_offset < byte_size) {
+ while (data_offset < *byte_size) {
if (NGRN >= 8)
return false;
@@ -2267,7 +2264,10 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
if (!reg_ctx)
return return_valobj_sp;
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
@@ -2276,7 +2276,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
bool success = false;
if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
// Extract the register context so we can read arguments from registers
- if (byte_size <= 8) {
+ if (*byte_size <= 8) {
const RegisterInfo *x0_reg_info =
reg_ctx->GetRegisterInfoByName("x0", 0);
if (x0_reg_info) {
@@ -2284,7 +2284,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
case 16: // uint128_t
@@ -2294,10 +2294,10 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
reg_ctx->GetRegisterInfoByName("x1", 0);
if (x1_reg_info) {
- if (byte_size <=
+ if (*byte_size <=
x0_reg_info->byte_size + x1_reg_info->byte_size) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order =
exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue x0_reg_value;
@@ -2362,7 +2362,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
- if (byte_size <= sizeof(long double)) {
+ if (*byte_size <= sizeof(long double)) {
const RegisterInfo *v0_reg_info =
reg_ctx->GetRegisterInfoByName("v0", 0);
RegisterValue v0_value;
@@ -2370,13 +2370,13 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
DataExtractor data;
if (v0_value.GetData(data)) {
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = data.GetDouble(&offset);
success = true;
- } else if (byte_size == sizeof(long double)) {
+ } else if (*byte_size == sizeof(long double)) {
value.GetScalar() = data.GetLongDouble(&offset);
success = true;
}
@@ -2390,14 +2390,14 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl(
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
- if (byte_size > 0) {
+ if (*byte_size > 0) {
const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
if (v0_info) {
- if (byte_size <= v0_info->byte_size) {
+ if (*byte_size <= v0_info->byte_size) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(v0_info, reg_value)) {
diff --git a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
index 2dd7337542db..7a9444c775f4 100644
--- a/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
+++ b/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABIMacOSX_arm64_h_
#define liblldb_ABIMacOSX_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
index 9e5e39ec28ca..a297bd1473b2 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
@@ -9,19 +9,13 @@
#include "ABIMacOSX_i386.h"
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
@@ -29,6 +23,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -714,13 +710,10 @@ size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; }
ABISP
ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
if ((arch.GetTriple().getArch() == llvm::Triple::x86) &&
(arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() ||
arch.GetTriple().isWatchOS())) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABIMacOSX_i386(process_sp));
- return g_abi_sp;
+ return ABISP(new ABIMacOSX_i386(process_sp));
}
return ABISP();
}
@@ -831,18 +824,15 @@ bool ABIMacOSX_i386::GetArgumentValues(Thread &thread,
// We currently only support extracting values with Clang QualTypes. Do we
// care about others?
CompilerType compiler_type(value->GetCompilerType());
- if (compiler_type) {
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (bit_size) {
bool is_signed;
-
- if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread), is_signed,
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed))
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed,
thread.GetProcess().get(), current_stack_argument);
- } else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread), false,
+ else if (compiler_type.IsPointerType())
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false,
thread.GetProcess().get(), current_stack_argument);
- }
}
}
@@ -943,14 +933,15 @@ ABIMacOSX_i386::GetReturnValueObjectImpl(Thread &thread,
bool is_signed;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- size_t bit_width = compiler_type.GetBitSize(&thread);
-
+ llvm::Optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
+ if (!bit_width)
+ return return_valobj_sp;
unsigned eax_id =
reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
unsigned edx_id =
reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
- switch (bit_width) {
+ switch (*bit_width) {
default:
case 128:
// Scalar can't hold 128-bit literals, so we don't handle this
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
index e026e3248672..536132d02586 100644
--- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
+++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABIMacOSX_i386_h_
#define liblldb_ABIMacOSX_i386_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Value.h"
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
index af7ac469e6db..b93a8525010c 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp
@@ -9,19 +9,13 @@
#include "ABISysV_arm.h"
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -30,6 +24,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Utility/ARMDefines.h"
@@ -1328,16 +1324,13 @@ size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type != llvm::Triple::Apple) {
if ((arch_type == llvm::Triple::arm) ||
(arch_type == llvm::Triple::thumb)) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_arm(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_arm(process_sp));
}
}
@@ -1447,10 +1440,7 @@ bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
~1ull; // clear bit zero since the CPSR will take care of the mode for us
// Set "pc" to the address requested
- if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr))
- return false;
-
- return true;
+ return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
}
bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
@@ -1481,10 +1471,10 @@ bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
if (compiler_type) {
bool is_signed = false;
size_t bit_width = 0;
- if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = compiler_type.GetBitSize(&thread);
- } else if (compiler_type.IsPointerOrReferenceType()) {
- bit_width = compiler_type.GetBitSize(&thread);
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
+ compiler_type.IsPointerOrReferenceType()) {
+ if (llvm::Optional<uint64_t> size = compiler_type.GetBitSize(&thread))
+ bit_width = *size;
} else {
// We only handle integer, pointer and reference types currently...
return false;
@@ -1590,11 +1580,13 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
const RegisterInfo *r0_reg_info =
reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
- size_t bit_width = compiler_type.GetBitSize(&thread);
- size_t byte_size = compiler_type.GetByteSize(&thread);
+ llvm::Optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
+ if (!bit_width || !byte_size)
+ return return_valobj_sp;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 64: {
@@ -1641,28 +1633,28 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
UINT32_MAX;
value.GetScalar() = ptr;
} else if (compiler_type.IsVectorType(nullptr, nullptr)) {
- if (IsArmHardFloat(thread) && (byte_size == 8 || byte_size == 16)) {
+ if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
is_vfp_candidate = true;
vfp_byte_size = 8;
- vfp_count = (byte_size == 8 ? 1 : 2);
- } else if (byte_size <= 16) {
+ vfp_count = (*byte_size == 8 ? 1 : 2);
+ } else if (*byte_size <= 16) {
DataBufferHeap buffer(16, 0);
uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
- for (uint32_t i = 0; 4 * i < byte_size; ++i) {
+ for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
buffer_ptr[i] =
reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
}
- value.SetBytes(buffer.GetBytes(), byte_size);
+ value.SetBytes(buffer.GetBytes(), *byte_size);
} else {
- if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
+ if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
return return_valobj_sp;
}
} else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
if (float_count == 1 && !is_complex) {
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 64: {
@@ -1710,9 +1702,9 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
} else if (is_complex && float_count == 2) {
if (IsArmHardFloat(thread)) {
is_vfp_candidate = true;
- vfp_byte_size = byte_size / 2;
+ vfp_byte_size = *byte_size / 2;
vfp_count = 2;
- } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8,
+ } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
value))
return return_valobj_sp;
} else
@@ -1725,19 +1717,21 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
compiler_type.IsHomogeneousAggregate(&base_type);
if (homogeneous_count > 0 && homogeneous_count <= 4) {
+ llvm::Optional<uint64_t> base_byte_size =
+ base_type.GetByteSize(nullptr);
if (base_type.IsVectorType(nullptr, nullptr)) {
- uint64_t base_byte_size = base_type.GetByteSize(nullptr);
- if (base_byte_size == 8 || base_byte_size == 16) {
+ if (base_byte_size &&
+ (*base_byte_size == 8 || *base_byte_size == 16)) {
is_vfp_candidate = true;
vfp_byte_size = 8;
- vfp_count =
- (base_type.GetByteSize(nullptr) == 8 ? homogeneous_count
- : homogeneous_count * 2);
+ vfp_count = (*base_byte_size == 8 ? homogeneous_count
+ : homogeneous_count * 2);
}
} else if (base_type.IsFloatingPointType(float_count, is_complex)) {
if (float_count == 1 && !is_complex) {
is_vfp_candidate = true;
- vfp_byte_size = base_type.GetByteSize(nullptr);
+ if (base_byte_size)
+ vfp_byte_size = *base_byte_size;
vfp_count = homogeneous_count;
}
}
@@ -1752,12 +1746,14 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
compiler_type.GetFieldAtIndex(index, name, NULL, NULL, NULL);
if (base_type.IsFloatingPointType(float_count, is_complex)) {
+ llvm::Optional<uint64_t> base_byte_size =
+ base_type.GetByteSize(nullptr);
if (float_count == 2 && is_complex) {
- if (index != 0 &&
- vfp_byte_size != base_type.GetByteSize(nullptr))
+ if (index != 0 && base_byte_size &&
+ vfp_byte_size != *base_byte_size)
break;
- else
- vfp_byte_size = base_type.GetByteSize(nullptr);
+ else if (base_byte_size)
+ vfp_byte_size = *base_byte_size;
} else
break;
} else
@@ -1773,13 +1769,13 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
}
}
- if (byte_size <= 4) {
+ if (*byte_size <= 4) {
RegisterValue r0_reg_value;
uint32_t raw_value =
reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
- value.SetBytes(&raw_value, byte_size);
+ value.SetBytes(&raw_value, *byte_size);
} else if (!is_vfp_candidate) {
- if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value))
+ if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
return return_valobj_sp;
}
} else {
@@ -1791,7 +1787,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
ProcessSP process_sp(thread.GetProcess());
ByteOrder byte_order = process_sp->GetByteOrder();
- DataBufferSP data_sp(new DataBufferHeap(byte_size, 0));
+ DataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
uint32_t data_offset = 0;
for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
@@ -1826,7 +1822,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
}
}
- if (data_offset == byte_size) {
+ if (data_offset == *byte_size) {
DataExtractor data;
data.SetByteOrder(byte_order);
data.SetAddressByteSize(process_sp->GetAddressByteSize());
diff --git a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
index f046968c213d..7f2d658541ab 100644
--- a/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
+++ b/source/Plugins/ABI/SysV-arm/ABISysV_arm.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_arm_h_
#define liblldb_ABISysV_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index 2c221689954c..dd3f47303be5 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -9,19 +9,13 @@
#include "ABISysV_arm64.h"
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -31,6 +25,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "Utility/ARM64_DWARF_Registers.h"
@@ -1671,15 +1667,12 @@ size_t ABISysV_arm64::GetRedZoneSize() const { return 128; }
ABISP
ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
if (vendor_type != llvm::Triple::Apple) {
if (arch_type == llvm::Triple::aarch64) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_arm64(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_arm64(process_sp));
}
}
@@ -1774,10 +1767,13 @@ bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const {
if (value_type) {
bool is_signed = false;
size_t bit_width = 0;
+ llvm::Optional<uint64_t> bit_size = value_type.GetBitSize(&thread);
+ if (!bit_size)
+ return false;
if (value_type.IsIntegerOrEnumerationType(is_signed)) {
- bit_width = value_type.GetBitSize(&thread);
+ bit_width = *bit_size;
} else if (value_type.IsPointerOrReferenceType()) {
- bit_width = value_type.GetBitSize(&thread);
+ bit_width = *bit_size;
} else {
// We only handle integer, pointer and reference types currently...
return false;
@@ -2090,13 +2086,13 @@ static bool LoadValueFromConsecutiveGPRRegisters(
uint32_t &NGRN, // NGRN (see ABI documentation)
uint32_t &NSRN, // NSRN (see ABI documentation)
DataExtractor &data) {
- const size_t byte_size = value_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size = value_type.GetByteSize(nullptr);
- if (byte_size == 0)
+ if (byte_size || *byte_size == 0)
return false;
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
Status error;
@@ -2108,7 +2104,9 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) {
if (!base_type)
return false;
- const size_t base_byte_size = base_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> base_byte_size = base_type.GetByteSize(nullptr);
+ if (!base_byte_size)
+ return false;
uint32_t data_offset = 0;
for (uint32_t i = 0; i < homogeneous_count; ++i) {
@@ -2119,7 +2117,7 @@ static bool LoadValueFromConsecutiveGPRRegisters(
if (reg_info == nullptr)
return false;
- if (base_byte_size > reg_info->byte_size)
+ if (*base_byte_size > reg_info->byte_size)
return false;
RegisterValue reg_value;
@@ -2128,11 +2126,11 @@ static bool LoadValueFromConsecutiveGPRRegisters(
return false;
// Make sure we have enough room in "heap_data_ap"
- if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize()) {
+ if ((data_offset + *base_byte_size) <= heap_data_ap->GetByteSize()) {
const size_t bytes_copied = reg_value.GetAsMemoryData(
- reg_info, heap_data_ap->GetBytes() + data_offset, base_byte_size,
+ reg_info, heap_data_ap->GetBytes() + data_offset, *base_byte_size,
byte_order, error);
- if (bytes_copied != base_byte_size)
+ if (bytes_copied != *base_byte_size)
return false;
data_offset += bytes_copied;
++NSRN;
@@ -2147,10 +2145,10 @@ static bool LoadValueFromConsecutiveGPRRegisters(
}
const size_t max_reg_byte_size = 16;
- if (byte_size <= max_reg_byte_size) {
- size_t bytes_left = byte_size;
+ if (*byte_size <= max_reg_byte_size) {
+ size_t bytes_left = *byte_size;
uint32_t data_offset = 0;
- while (data_offset < byte_size) {
+ while (data_offset < *byte_size) {
if (NGRN >= 8)
return false;
@@ -2235,7 +2233,10 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
if (!reg_ctx)
return return_valobj_sp;
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) {
@@ -2244,7 +2245,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
bool success = false;
if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) {
// Extract the register context so we can read arguments from registers
- if (byte_size <= 8) {
+ if (*byte_size <= 8) {
const RegisterInfo *x0_reg_info = nullptr;
x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
LLDB_REGNUM_GENERIC_ARG1);
@@ -2253,7 +2254,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info,
0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
case 16: // uint128_t
@@ -2264,10 +2265,10 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
LLDB_REGNUM_GENERIC_ARG2);
if (x1_reg_info) {
- if (byte_size <=
+ if (*byte_size <=
x0_reg_info->byte_size + x1_reg_info->byte_size) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order =
exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue x0_reg_value;
@@ -2332,7 +2333,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
- if (byte_size <= sizeof(long double)) {
+ if (*byte_size <= sizeof(long double)) {
const RegisterInfo *v0_reg_info =
reg_ctx->GetRegisterInfoByName("v0", 0);
RegisterValue v0_value;
@@ -2340,13 +2341,13 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
DataExtractor data;
if (v0_value.GetData(data)) {
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = data.GetDouble(&offset);
success = true;
- } else if (byte_size == sizeof(long double)) {
+ } else if (*byte_size == sizeof(long double)) {
value.GetScalar() = data.GetLongDouble(&offset);
success = true;
}
@@ -2359,13 +2360,13 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
if (success)
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsVector && byte_size <= 16) {
- if (byte_size > 0) {
+ } else if (type_flags & eTypeIsVector && *byte_size <= 16) {
+ if (*byte_size > 0) {
const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
if (v0_info) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(v0_info, reg_value)) {
@@ -2382,7 +2383,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
}
}
} else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
- (type_flags & eTypeIsVector && byte_size > 16)) {
+ (type_flags & eTypeIsVector && *byte_size > 16)) {
DataExtractor data;
uint32_t NGRN = 0; // Search ABI docs for NGRN
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
index 8d23c2419bab..b36b4547e626 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_arm64_h_
#define liblldb_ABISysV_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
index a30416cf5a8e..ca40e9a04d7c 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
@@ -9,16 +9,11 @@
#include "ABISysV_hexagon.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DerivedTypes.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -32,6 +27,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -1020,11 +1016,8 @@ size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_hexagon(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_hexagon(process_sp));
}
return ABISP();
}
diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
index 5a6809371d9f..6e39c0792e2a 100644
--- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
+++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h
@@ -11,10 +11,6 @@
#ifndef liblldb_ABISysV_hexagon_h_
#define liblldb_ABISysV_hexagon_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
index e7ddfccea338..3358eb8c2774 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp
@@ -8,16 +8,11 @@
#include "ABISysV_i386.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -31,6 +26,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -203,12 +199,9 @@ 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().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(new ABISysV_i386(process_sp));
}
}
return ABISP();
@@ -315,15 +308,14 @@ bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const {
// Currently: Support for extracting values with Clang QualTypes only.
CompilerType compiler_type(value->GetCompilerType());
- if (compiler_type) {
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (bit_size) {
bool is_signed;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread), is_signed,
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed,
thread.GetProcess().get(), current_stack_argument);
} else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(),
- compiler_type.GetBitSize(&thread), false,
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false,
thread.GetProcess().get(), current_stack_argument);
}
}
@@ -521,7 +513,10 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
(type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point'
{
value.SetValueType(Value::eValueTypeScalar);
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
bool success = false;
if (type_flags & eTypeIsInteger) // 'Integral' except enum
@@ -535,7 +530,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
0xffffffff)
<< 32;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
@@ -591,7 +586,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsFloat) // 'Floating Point'
{
- if (byte_size <= 12) // handles float, double, long double, __float80
+ if (*byte_size <= 12) // handles float, double, long double, __float80
{
const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0);
RegisterValue st0_value;
@@ -602,21 +597,20 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
lldb::offset_t offset = 0;
long double value_long_double = data.GetLongDouble(&offset);
- if (byte_size == 4) // float is 4 bytes
- {
+ // float is 4 bytes.
+ if (*byte_size == 4) {
float value_float = (float)value_long_double;
value.GetScalar() = value_float;
success = true;
- } else if (byte_size == 8) // double is 8 bytes
- {
+ } else if (*byte_size == 8) {
+ // double is 8 bytes
// On Android Platform: long double is also 8 bytes It will be
// handled here only.
double value_double = (double)value_long_double;
value.GetScalar() = value_double;
success = true;
- } else if (byte_size ==
- 12) // long double and __float80 are 12 bytes on i386
- {
+ } else if (*byte_size == 12) {
+ // long double and __float80 are 12 bytes on i386.
value.GetScalar() = value_long_double;
success = true;
}
@@ -626,7 +620,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
if (success)
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (byte_size == 16) // handles __float128
+ } else if (*byte_size == 16) // handles __float128
{
lldb::addr_t storage_addr = (uint32_t)(
thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) &
@@ -644,18 +638,19 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
// ToDo: Yet to be implemented
} else if (type_flags & eTypeIsVector) // 'Packed'
{
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size > 0) {
const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
if (vec_reg == nullptr)
vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
if (vec_reg) {
- if (byte_size <= vec_reg->byte_size) {
+ if (*byte_size <= vec_reg->byte_size) {
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(vec_reg, reg_value)) {
@@ -672,14 +667,14 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple(
}
}
}
- } else if (byte_size <= vec_reg->byte_size * 2) {
+ } else if (*byte_size <= vec_reg->byte_size * 2) {
const RegisterInfo *vec_reg2 =
reg_ctx->GetRegisterInfoByName("xmm1", 0);
if (vec_reg2) {
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue reg_value;
RegisterValue reg_value2;
diff --git a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
index 4dce54c4f073..336a2754c6ca 100644
--- a/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
+++ b/source/Plugins/ABI/SysV-i386/ABISysV_i386.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_i386_h_
#define liblldb_ABISysV_i386_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
index ce02f8677a63..6f3d2e3b3696 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp
@@ -9,16 +9,11 @@
#include "ABISysV_mips.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -32,6 +27,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -560,13 +556,10 @@ size_t ABISysV_mips::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
if ((arch_type == llvm::Triple::mips) ||
(arch_type == llvm::Triple::mipsel)) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_mips(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_mips(process_sp));
}
return ABISP();
}
@@ -819,9 +812,11 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
// In MIPS register "r2" (v0) holds the integer function return values
const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0);
- size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
+ if (!bit_width)
+ return return_valobj_sp;
if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 64: {
@@ -880,7 +875,7 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0);
if (count != 1 && is_complex)
return return_valobj_sp;
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 32:
@@ -912,7 +907,7 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl(
lldb::offset_t offset = 0;
if (count == 1 && !is_complex) {
- switch (bit_width) {
+ switch (*bit_width) {
default:
return return_valobj_sp;
case 64: {
diff --git a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
index 0de8e7751fce..d23dbe9d97bd 100644
--- a/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
+++ b/source/Plugins/ABI/SysV-mips/ABISysV_mips.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_mips_h_
#define liblldb_ABISysV_mips_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
index b958abf25637..1d6738d9fda9 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp
@@ -9,16 +9,11 @@
#include "ABISysV_mips64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -32,6 +27,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -560,13 +556,10 @@ size_t ABISysV_mips64::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
if ((arch_type == llvm::Triple::mips64) ||
(arch_type == llvm::Triple::mips64el)) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_mips64(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_mips64(process_sp));
}
return ABISP();
}
@@ -769,7 +762,10 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
Target *target = exe_ctx.GetTargetPtr();
const ArchSpec target_arch = target->GetArchitecture();
ByteOrder target_byte_order = target_arch.GetByteOrder();
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr);
uint32_t fp_flag =
target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask;
@@ -788,7 +784,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
@@ -829,7 +825,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
// Don't handle complex yet.
} else if (IsSoftFloat(fp_flag)) {
uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0);
- switch (byte_size) {
+ switch (*byte_size) {
case 4:
value.GetScalar() = *((float *)(&raw_value));
success = true;
@@ -854,7 +850,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
}
} else {
- if (byte_size <= sizeof(long double)) {
+ if (*byte_size <= sizeof(long double)) {
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
RegisterValue f0_value;
@@ -865,13 +861,13 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
f0_value.GetData(f0_data);
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = (float)f0_data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = (double)f0_data.GetDouble(&offset);
success = true;
- } else if (byte_size == sizeof(long double)) {
+ } else if (*byte_size == sizeof(long double)) {
const RegisterInfo *f2_info =
reg_ctx->GetRegisterInfoByName("f2", 0);
RegisterValue f2_value;
@@ -886,21 +882,21 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
if (target_byte_order == eByteOrderLittle) {
copy_from_extractor = &f0_data;
copy_from_extractor->CopyByteOrderedData(
- 0, 8, data_sp->GetBytes(), byte_size - 8, target_byte_order);
+ 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
f2_value.GetData(f2_data);
copy_from_extractor = &f2_data;
copy_from_extractor->CopyByteOrderedData(
- 0, 8, data_sp->GetBytes() + 8, byte_size - 8,
+ 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
target_byte_order);
} else {
copy_from_extractor = &f0_data;
copy_from_extractor->CopyByteOrderedData(
- 0, 8, data_sp->GetBytes() + 8, byte_size - 8,
+ 0, 8, data_sp->GetBytes() + 8, *byte_size - 8,
target_byte_order);
f2_value.GetData(f2_data);
copy_from_extractor = &f2_data;
copy_from_extractor->CopyByteOrderedData(
- 0, 8, data_sp->GetBytes(), byte_size - 8, target_byte_order);
+ 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order);
}
return_valobj_sp = ValueObjectConstResult::Create(
@@ -917,7 +913,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
} else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
type_flags & eTypeIsVector) {
// Any structure of up to 16 bytes in size is returned in the registers.
- if (byte_size <= 16) {
+ if (*byte_size <= 16) {
DataBufferSP data_sp(new DataBufferHeap(16, 0));
DataExtractor return_ext(data_sp, target_byte_order,
target->GetArchitecture().GetAddressByteSize());
@@ -975,8 +971,10 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
CompilerType field_compiler_type =
return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_byte_width =
+ llvm::Optional<uint64_t> field_byte_width =
field_compiler_type.GetByteSize(nullptr);
+ if (!field_byte_width)
+ return return_valobj_sp;
DataExtractor *copy_from_extractor = nullptr;
uint64_t return_value[2];
@@ -984,7 +982,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
if (idx == 0) {
// This case is for long double type.
- if (field_byte_width == 16) {
+ if (*field_byte_width == 16) {
// If structure contains long double type, then it is returned
// in fp0/fp1 registers.
@@ -1002,7 +1000,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
return_value[0] = f1_data.GetU64(&offset);
}
- f0_data.SetData(return_value, field_byte_width,
+ f0_data.SetData(return_value, *field_byte_width,
target_byte_order);
}
copy_from_extractor = &f0_data; // This is in f0, copy from
@@ -1016,13 +1014,13 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
// Sanity check to avoid crash
if (!copy_from_extractor ||
- field_byte_width > copy_from_extractor->GetByteSize())
+ *field_byte_width > copy_from_extractor->GetByteSize())
return return_valobj_sp;
// copy the register contents into our data buffer
copy_from_extractor->CopyByteOrderedData(
- 0, field_byte_width,
- data_sp->GetBytes() + (field_bit_offset / 8), field_byte_width,
+ 0, *field_byte_width,
+ data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width,
target_byte_order);
}
@@ -1045,12 +1043,12 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_byte_width =
+ llvm::Optional<uint64_t> field_byte_width =
field_compiler_type.GetByteSize(nullptr);
// if we don't know the size of the field (e.g. invalid type), just
// bail out
- if (field_byte_width == 0)
+ if (!field_byte_width || *field_byte_width == 0)
break;
uint32_t field_byte_offset = field_bit_offset / 8;
@@ -1062,24 +1060,24 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
if (integer_bytes < 8) {
// We have not yet consumed r2 completely.
- if (integer_bytes + field_byte_width + padding <= 8) {
+ if (integer_bytes + *field_byte_width + padding <= 8) {
// This field fits in r2, copy its value from r2 to our result
// structure
- integer_bytes = integer_bytes + field_byte_width +
+ integer_bytes = integer_bytes + *field_byte_width +
padding; // Increase the consumed bytes.
use_r2 = 1;
} else {
// There isn't enough space left in r2 for this field, so this
// will be in r3.
- integer_bytes = integer_bytes + field_byte_width +
+ integer_bytes = integer_bytes + *field_byte_width +
padding; // Increase the consumed bytes.
use_r3 = 1;
}
}
// We already have consumed at-least 8 bytes that means r2 is done,
// and this field will be in r3. Check if this field can fit in r3.
- else if (integer_bytes + field_byte_width + padding <= 16) {
- integer_bytes = integer_bytes + field_byte_width + padding;
+ else if (integer_bytes + *field_byte_width + padding <= 16) {
+ integer_bytes = integer_bytes + *field_byte_width + padding;
use_r3 = 1;
} else {
// There isn't any space left for this field, this should not
@@ -1092,7 +1090,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl(
}
// Vector types up to 16 bytes are returned in GP return registers
if (type_flags & eTypeIsVector) {
- if (byte_size <= 8)
+ if (*byte_size <= 8)
use_r2 = 1;
else {
use_r2 = 1;
diff --git a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
index 6258c08e35f9..c7670f467114 100644
--- a/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
+++ b/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_mips64_h_
#define liblldb_ABISysV_mips64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
index e93dcdbe1a59..1fe7a6718a91 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
@@ -9,16 +9,11 @@
#include "ABISysV_ppc.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -32,6 +27,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -224,11 +220,8 @@ size_t ABISysV_ppc::GetRedZoneSize() const { return 224; }
ABISP
ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::ppc) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_ppc(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_ppc(process_sp));
}
return ABISP();
}
@@ -405,19 +398,18 @@ bool ABISysV_ppc::GetArgumentValues(Thread &thread, ValueList &values) const {
// We currently only support extracting values with Clang QualTypes. Do we
// care about others?
CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
return false;
bool is_signed;
-
- if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- is_signed, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
- } else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- false, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
- }
+ if (compiler_type.IsIntegerOrEnumerationType(is_signed))
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
+ else if (compiler_type.IsPointerType())
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
}
return true;
@@ -474,8 +466,13 @@ Status ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
error.SetErrorString(
"We don't support returning complex values at present");
else {
- size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
- if (bit_width <= 64) {
+ llvm::Optional<uint64_t> bit_width =
+ compiler_type.GetBitSize(frame_sp.get());
+ if (!bit_width) {
+ error.SetErrorString("can't get type size");
+ return error;
+ }
+ if (*bit_width <= 64) {
DataExtractor data;
Status data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
@@ -533,11 +530,14 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
if (type_flags & eTypeIsInteger) {
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("r3", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
@@ -577,18 +577,19 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double)) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0);
RegisterValue f1_value;
if (reg_ctx->ReadRegister(f1_info, f1_value)) {
DataExtractor data;
if (f1_value.GetData(data)) {
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = (double)data.GetDouble(&offset);
success = true;
}
@@ -610,15 +611,16 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size > 0) {
const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0);
if (altivec_reg) {
- if (byte_size <= altivec_reg->byte_size) {
+ if (*byte_size <= altivec_reg->byte_size) {
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
@@ -627,9 +629,10 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple(
altivec_reg, heap_data_ap->GetBytes(),
heap_data_ap->GetByteSize(), byte_order, error)) {
DataExtractor data(DataBufferSP(heap_data_ap.release()),
- byte_order, process_sp->GetTarget()
- .GetArchitecture()
- .GetAddressByteSize());
+ byte_order,
+ process_sp->GetTarget()
+ .GetArchitecture()
+ .GetAddressByteSize());
return_valobj_sp = ValueObjectConstResult::Create(
&thread, return_compiler_type, ConstString(""), data);
}
@@ -659,11 +662,13 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
+ if (!bit_width)
+ return return_valobj_sp;
if (return_compiler_type.IsAggregateType()) {
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
- if (bit_width <= 128) {
+ if (*bit_width <= 128) {
ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
DataBufferSP data_sp(new DataBufferHeap(16, 0));
DataExtractor return_ext(data_sp, target_byte_order,
@@ -701,15 +706,18 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> field_bit_width =
+ field_compiler_type.GetBitSize(&thread);
+ if (!field_bit_width)
+ return return_valobj_sp;
// If there are any unaligned fields, this is stored in memory.
- if (field_bit_offset % field_bit_width != 0) {
+ if (field_bit_offset % *field_bit_width != 0) {
is_memory = true;
break;
}
- uint32_t field_byte_width = field_bit_width / 8;
+ uint32_t field_byte_width = *field_bit_width / 8;
uint32_t field_byte_offset = field_bit_offset / 8;
DataExtractor *copy_from_extractor = nullptr;
@@ -742,13 +750,13 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl(
}
} else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
// Structs with long doubles are always passed in memory.
- if (field_bit_width == 128) {
+ if (*field_bit_width == 128) {
is_memory = true;
break;
- } else if (field_bit_width == 64) {
+ } else if (*field_bit_width == 64) {
copy_from_offset = 0;
fp_bytes += field_byte_width;
- } else if (field_bit_width == 32) {
+ } else if (*field_bit_width == 32) {
// This one is kind of complicated. If we are in an "eightbyte"
// with another float, we'll be stuffed into an xmm register with
// it. If we are in an "eightbyte" with one or more ints, then we
diff --git a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
index df3ebe83faf8..3559cbb45200 100644
--- a/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
+++ b/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_ppc_h_
#define liblldb_ABISysV_ppc_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
index d0140a0c894a..fb46b7dc7fb6 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
@@ -9,18 +9,13 @@
#include "ABISysV_ppc64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "Utility/PPC64LE_DWARF_Registers.h"
#include "Utility/PPC64_DWARF_Registers.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -35,6 +30,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "clang/AST/ASTContext.h"
@@ -284,18 +280,19 @@ bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const {
// We currently only support extracting values with Clang QualTypes. Do we
// care about others?
CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
return false;
bool is_signed;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- is_signed, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
} else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- false, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
}
}
@@ -353,8 +350,13 @@ Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
error.SetErrorString(
"We don't support returning complex values at present");
else {
- size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
- if (bit_width <= 64) {
+ llvm::Optional<uint64_t> bit_width =
+ compiler_type.GetBitSize(frame_sp.get());
+ if (!bit_width) {
+ error.SetErrorString("can't get size of type");
+ return error;
+ }
+ if (*bit_width <= 64) {
DataExtractor data;
Status data_error;
size_t num_bytes = new_value_sp->GetData(data, data_error);
@@ -575,7 +577,7 @@ private:
ReturnValueExtractor(Thread &thread, CompilerType &type,
RegisterContext *reg_ctx, ProcessSP process_sp)
: m_thread(thread), m_type(type),
- m_byte_size(m_type.GetByteSize(nullptr)),
+ m_byte_size(m_type.GetByteSize(nullptr).getValueOr(0)),
m_data_ap(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx),
m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()),
m_addr_size(
@@ -643,7 +645,7 @@ private:
uint64_t raw_data;
auto reg = GetFPR(reg_index);
if (!reg.GetRawData(raw_data))
- return ValueSP();
+ return {};
// build value from data
ValueSP value_sp(NewScalarValue(type));
@@ -651,8 +653,10 @@ private:
DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size);
offset_t offset = 0;
- size_t byte_size = type.GetByteSize(nullptr);
- switch (byte_size) {
+ llvm::Optional<uint64_t> byte_size = type.GetByteSize(nullptr);
+ if (!byte_size)
+ return {};
+ switch (*byte_size) {
case sizeof(float):
value_sp->GetScalar() = (float)de.GetDouble(&offset);
break;
@@ -759,7 +763,7 @@ private:
uint64_t addr;
auto reg = GetGPR(0);
if (!reg.GetRawData(addr))
- return ValueObjectSP();
+ return {};
Status error;
size_t rc = m_process_sp->ReadMemory(addr, m_data_ap->GetBytes(),
@@ -773,37 +777,39 @@ private:
// get number of children
const bool omit_empty_base_classes = true;
- uint32_t n = m_type.GetNumChildren(omit_empty_base_classes);
+ uint32_t n = m_type.GetNumChildren(omit_empty_base_classes, nullptr);
if (!n) {
LLDB_LOG(m_log, LOG_PREFIX "No children found in struct");
- return ValueObjectSP();
+ return {};
}
// case 2: homogeneous double or float aggregate
CompilerType elem_type;
if (m_type.IsHomogeneousAggregate(&elem_type)) {
uint32_t type_flags = elem_type.GetTypeInfo();
- uint64_t elem_size = elem_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> elem_size = elem_type.GetByteSize(nullptr);
+ if (!elem_size)
+ return {};
if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) {
LLDB_LOG(m_log,
LOG_PREFIX "Unexpected type found in homogeneous aggregate");
- return ValueObjectSP();
+ return {};
}
for (uint32_t i = 0; i < n; i++) {
ValueSP val_sp = GetFloatValue(elem_type, i);
if (!val_sp)
- return ValueObjectSP();
+ return {};
// copy to buffer
Status error;
size_t rc = val_sp->GetScalar().GetAsMemoryData(
- m_data_ap->GetBytes() + m_dst_offs, elem_size, m_byte_order, error);
- if (rc != elem_size) {
+ m_data_ap->GetBytes() + m_dst_offs, *elem_size, m_byte_order, error);
+ if (rc != *elem_size) {
LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data");
- return ValueObjectSP();
+ return {};
}
- m_dst_offs += elem_size;
+ m_dst_offs += *elem_size;
}
return BuildValueObject();
}
diff --git a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
index 52765a773c0b..54f461e1001b 100644
--- a/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
+++ b/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_ppc64_h_
#define liblldb_ABISysV_ppc64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
index 31e2825c0fa2..d8056ea7d356 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp
@@ -9,16 +9,11 @@
#include "ABISysV_s390x.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -32,6 +27,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -206,11 +202,8 @@ size_t ABISysV_s390x::GetRedZoneSize() const { return 0; }
ABISP
ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::systemz) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_s390x(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_s390x(process_sp));
}
return ABISP();
}
@@ -383,18 +376,19 @@ bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const {
// We currently only support extracting values with Clang QualTypes. Do we
// care about others?
CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
return false;
bool is_signed;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- is_signed, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
} else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- false, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
}
}
@@ -452,8 +446,13 @@ Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
error.SetErrorString(
"We don't support returning complex values at present");
else {
- size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
- if (bit_width <= 64) {
+ llvm::Optional<uint64_t> bit_width =
+ compiler_type.GetBitSize(frame_sp.get());
+ if (!bit_width) {
+ error.SetErrorString("can't get type size");
+ return error;
+ }
+ if (*bit_width <= 64) {
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
RegisterValue f0_value;
DataExtractor data;
@@ -513,13 +512,15 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
bool success = false;
if (type_flags & eTypeIsInteger) {
- // Extract the register context so we can read arguments from registers
-
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ // Extract the register context so we can read arguments from registers.
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("r2", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
@@ -559,21 +560,22 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple(
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double)) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0);
RegisterValue f0_value;
if (reg_ctx->ReadRegister(f0_info, f0_value)) {
DataExtractor data;
if (f0_value.GetData(data)) {
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = (double)data.GetDouble(&offset);
success = true;
- } else if (byte_size == sizeof(long double)) {
+ } else if (*byte_size == sizeof(long double)) {
// Don't handle long double yet.
}
}
diff --git a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
index 5e3d20d7898b..5433ebb4593e 100644
--- a/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
+++ b/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_s390x_h_
#define liblldb_ABISysV_s390x_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
@@ -61,9 +57,7 @@ public:
bool CodeAddressIsValid(lldb::addr_t pc) override {
// Code addressed must be 2 byte aligned
- if (pc & 1ull)
- return false;
- return true;
+ return (pc & 1ull) == 0;
}
const lldb_private::RegisterInfo *
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 36ae3a49827c..dc3e475e3b8e 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
@@ -9,17 +9,12 @@
#include "ABISysV_x86_64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectMemory.h"
@@ -33,6 +28,7 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
@@ -1095,11 +1091,8 @@ size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
ABISP
ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
- static ABISP g_abi_sp;
if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
- if (!g_abi_sp)
- g_abi_sp.reset(new ABISysV_x86_64(process_sp));
- return g_abi_sp;
+ return ABISP(new ABISysV_x86_64(process_sp));
}
return ABISP();
}
@@ -1270,18 +1263,19 @@ bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
// We currently only support extracting values with Clang QualTypes. Do we
// care about others?
CompilerType compiler_type = value->GetCompilerType();
- if (!compiler_type)
+ llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
+ if (!bit_size)
return false;
bool is_signed;
if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- is_signed, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
} else if (compiler_type.IsPointerType()) {
- ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread),
- false, thread, argument_register_ids,
- current_argument_register, current_stack_argument);
+ ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
+ argument_register_ids, current_argument_register,
+ current_stack_argument);
}
}
@@ -1339,8 +1333,13 @@ Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
error.SetErrorString(
"We don't support returning complex values at present");
else {
- size_t bit_width = compiler_type.GetBitSize(frame_sp.get());
- if (bit_width <= 64) {
+ llvm::Optional<uint64_t> bit_width =
+ compiler_type.GetBitSize(frame_sp.get());
+ if (!bit_width) {
+ error.SetErrorString("can't get type size");
+ return error;
+ }
+ if (*bit_width <= 64) {
const RegisterInfo *xmm0_info =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
RegisterValue xmm0_value;
@@ -1403,11 +1402,14 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
if (type_flags & eTypeIsInteger) {
// Extract the register context so we can read arguments from registers
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (!byte_size)
+ return return_valobj_sp;
uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
reg_ctx->GetRegisterInfoByName("rax", 0), 0);
const bool is_signed = (type_flags & eTypeIsSigned) != 0;
- switch (byte_size) {
+ switch (*byte_size) {
default:
break;
@@ -1447,8 +1449,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
if (type_flags & eTypeIsComplex) {
// Don't handle complex yet.
} else {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size <= sizeof(long double)) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size <= sizeof(long double)) {
const RegisterInfo *xmm0_info =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
RegisterValue xmm0_value;
@@ -1456,13 +1459,13 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
DataExtractor data;
if (xmm0_value.GetData(data)) {
lldb::offset_t offset = 0;
- if (byte_size == sizeof(float)) {
+ if (*byte_size == sizeof(float)) {
value.GetScalar() = (float)data.GetFloat(&offset);
success = true;
- } else if (byte_size == sizeof(double)) {
+ } else if (*byte_size == sizeof(double)) {
value.GetScalar() = (double)data.GetDouble(&offset);
success = true;
- } else if (byte_size == sizeof(long double)) {
+ } else if (*byte_size == sizeof(long double)) {
// Don't handle long double since that can be encoded as 80 bit
// floats...
}
@@ -1485,19 +1488,20 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
} else if (type_flags & eTypeIsVector) {
- const size_t byte_size = return_compiler_type.GetByteSize(nullptr);
- if (byte_size > 0) {
+ llvm::Optional<uint64_t> byte_size =
+ return_compiler_type.GetByteSize(nullptr);
+ if (byte_size && *byte_size > 0) {
const RegisterInfo *altivec_reg =
reg_ctx->GetRegisterInfoByName("xmm0", 0);
if (altivec_reg == nullptr)
altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
if (altivec_reg) {
- if (byte_size <= altivec_reg->byte_size) {
+ if (*byte_size <= altivec_reg->byte_size) {
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue reg_value;
if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
@@ -1514,14 +1518,14 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
}
}
}
- } else if (byte_size <= altivec_reg->byte_size * 2) {
+ } else if (*byte_size <= altivec_reg->byte_size * 2) {
const RegisterInfo *altivec_reg2 =
reg_ctx->GetRegisterInfoByName("xmm1", 0);
if (altivec_reg2) {
ProcessSP process_sp(thread.GetProcess());
if (process_sp) {
std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
+ new DataBufferHeap(*byte_size, 0));
const ByteOrder byte_order = process_sp->GetByteOrder();
RegisterValue reg_value;
RegisterValue reg_value2;
@@ -1571,11 +1575,13 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
if (!reg_ctx_sp)
return return_valobj_sp;
- const size_t bit_width = return_compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
+ if (!bit_width)
+ return return_valobj_sp;
if (return_compiler_type.IsAggregateType()) {
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
- if (bit_width <= 128) {
+ if (*bit_width <= 128) {
ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
DataBufferSP data_sp(new DataBufferHeap(16, 0));
DataExtractor return_ext(data_sp, target_byte_order,
@@ -1622,20 +1628,21 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
idx, name, &field_bit_offset, nullptr, nullptr);
- const size_t field_bit_width = field_compiler_type.GetBitSize(&thread);
+ llvm::Optional<uint64_t> field_bit_width =
+ field_compiler_type.GetBitSize(&thread);
// if we don't know the size of the field (e.g. invalid type), just
// bail out
- if (field_bit_width == 0)
+ if (!field_bit_width || *field_bit_width == 0)
break;
// If there are any unaligned fields, this is stored in memory.
- if (field_bit_offset % field_bit_width != 0) {
+ if (field_bit_offset % *field_bit_width != 0) {
is_memory = true;
break;
}
- uint32_t field_byte_width = field_bit_width / 8;
+ uint32_t field_byte_width = *field_bit_width / 8;
uint32_t field_byte_offset = field_bit_offset / 8;
DataExtractor *copy_from_extractor = nullptr;
@@ -1668,10 +1675,10 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
}
} else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
// Structs with long doubles are always passed in memory.
- if (field_bit_width == 128) {
+ if (*field_bit_width == 128) {
is_memory = true;
break;
- } else if (field_bit_width == 64) {
+ } else if (*field_bit_width == 64) {
// These have to be in a single xmm register.
if (fp_bytes == 0)
copy_from_extractor = &xmm0_data;
@@ -1680,7 +1687,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
copy_from_offset = 0;
fp_bytes += field_byte_width;
- } else if (field_bit_width == 32) {
+ } else if (*field_bit_width == 32) {
// This one is kind of complicated. If we are in an "eightbyte"
// with another float, we'll be stuffed into an xmm register with
// it. If we are in an "eightbyte" with one or more ints, then we
diff --git a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
index 5b67e8656d36..4afc8c4cad62 100644
--- a/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
+++ b/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ABISysV_x86_64_h_
#define liblldb_ABISysV_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
index 1b7ecc88c35e..6993222ba5d4 100644
--- a/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -126,3 +126,33 @@ void ArchitectureArm::OverrideStopInfo(Thread &thread) const {
}
}
}
+
+addr_t ArchitectureArm::GetCallableLoadAddress(addr_t code_addr,
+ AddressClass addr_class) const {
+ bool is_alternate_isa = false;
+
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ case AddressClass::eCodeAlternateISA:
+ is_alternate_isa = true;
+ break;
+ default: break;
+ }
+
+ if ((code_addr & 2u) || is_alternate_isa)
+ return code_addr | 1u;
+ return code_addr;
+}
+
+addr_t ArchitectureArm::GetOpcodeLoadAddress(addr_t opcode_addr,
+ AddressClass addr_class) const {
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ default: break;
+ }
+ return opcode_addr & ~(1ull);
+}
diff --git a/source/Plugins/Architecture/Arm/ArchitectureArm.h b/source/Plugins/Architecture/Arm/ArchitectureArm.h
index 484c4a52fcc6..1a052c76b2c9 100644
--- a/source/Plugins/Architecture/Arm/ArchitectureArm.h
+++ b/source/Plugins/Architecture/Arm/ArchitectureArm.h
@@ -25,6 +25,12 @@ public:
void OverrideStopInfo(Thread &thread) const override;
+ lldb::addr_t GetCallableLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
+ lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
private:
static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
ArchitectureArm() = default;
diff --git a/source/Plugins/Architecture/CMakeLists.txt b/source/Plugins/Architecture/CMakeLists.txt
index 01365a64cf96..14ad91644595 100644
--- a/source/Plugins/Architecture/CMakeLists.txt
+++ b/source/Plugins/Architecture/CMakeLists.txt
@@ -1,2 +1,3 @@
add_subdirectory(Arm)
+add_subdirectory(Mips)
add_subdirectory(PPC64)
diff --git a/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
new file mode 100644
index 000000000000..0cbbd9922321
--- /dev/null
+++ b/source/Plugins/Architecture/Mips/ArchitectureMips.cpp
@@ -0,0 +1,241 @@
+//===-- ArchitectureMips.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/Mips/ArchitectureMips.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Log.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+ConstString ArchitectureMips::GetPluginNameStatic() {
+ return ConstString("mips");
+}
+
+void ArchitectureMips::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ "Mips-specific algorithms",
+ &ArchitectureMips::Create);
+}
+
+void ArchitectureMips::Terminate() {
+ PluginManager::UnregisterPlugin(&ArchitectureMips::Create);
+}
+
+std::unique_ptr<Architecture> ArchitectureMips::Create(const ArchSpec &arch) {
+ return arch.IsMIPS() ?
+ std::unique_ptr<Architecture>(new ArchitectureMips(arch)) : nullptr;
+}
+
+ConstString ArchitectureMips::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t ArchitectureMips::GetPluginVersion() { return 1; }
+
+addr_t ArchitectureMips::GetCallableLoadAddress(addr_t code_addr,
+ AddressClass addr_class) const {
+ bool is_alternate_isa = false;
+
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ case AddressClass::eCodeAlternateISA:
+ is_alternate_isa = true;
+ break;
+ default: break;
+ }
+
+ if ((code_addr & 2ull) || is_alternate_isa)
+ return code_addr | 1u;
+ return code_addr;
+}
+
+addr_t ArchitectureMips::GetOpcodeLoadAddress(addr_t opcode_addr,
+ AddressClass addr_class) const {
+ switch (addr_class) {
+ case AddressClass::eData:
+ case AddressClass::eDebug:
+ return LLDB_INVALID_ADDRESS;
+ default: break;
+ }
+ return opcode_addr & ~(1ull);
+}
+
+lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr,
+ Target &target) const {
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ Address resolved_addr;
+
+ SectionLoadList &section_load_list = target.GetSectionLoadList();
+ if (section_load_list.IsEmpty())
+ // No sections are loaded, so we must assume we are not running yet and
+ // need to operate only on file address.
+ target.ResolveFileAddress(addr, resolved_addr);
+ else
+ target.ResolveLoadAddress(addr, resolved_addr);
+
+ addr_t current_offset = 0;
+
+ // Get the function boundaries to make sure we don't scan back before the
+ // beginning of the current function.
+ ModuleSP temp_addr_module_sp(resolved_addr.GetModule());
+ if (temp_addr_module_sp) {
+ SymbolContext sc;
+ SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
+ temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr,
+ resolve_scope, sc);
+ Address sym_addr;
+ if (sc.function)
+ sym_addr = sc.function->GetAddressRange().GetBaseAddress();
+ else if (sc.symbol)
+ sym_addr = sc.symbol->GetAddress();
+
+ addr_t function_start = sym_addr.GetLoadAddress(&target);
+ if (function_start == LLDB_INVALID_ADDRESS)
+ function_start = sym_addr.GetFileAddress();
+
+ if (function_start)
+ current_offset = addr - function_start;
+ }
+
+ // If breakpoint address is start of function then we dont have to do
+ // anything.
+ if (current_offset == 0)
+ return addr;
+
+ ExecutionContext ctx;
+ target.CalculateExecutionContext(ctx);
+ auto insn = GetInstructionAtAddress(ctx, current_offset, addr);
+
+ if (nullptr == insn || !insn->HasDelaySlot())
+ return addr;
+
+ // Adjust the breakable address
+ uint64_t breakable_addr = addr - insn->GetOpcode().GetByteSize();
+ if (log)
+ log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64
+ " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n",
+ __FUNCTION__, addr, breakable_addr);
+
+ return breakable_addr;
+}
+
+Instruction *ArchitectureMips::GetInstructionAtAddress(
+ const ExecutionContext &exe_ctx, const Address &resolved_addr,
+ addr_t symbol_offset) const {
+
+ auto loop_count = symbol_offset / 2;
+
+ uint32_t arch_flags = m_arch.GetFlags();
+ bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16;
+ bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips;
+
+ if (loop_count > 3) {
+ // Scan previous 6 bytes
+ if (IsMips16 | IsMicromips)
+ loop_count = 3;
+ // For mips-only, instructions are always 4 bytes, so scan previous 4
+ // bytes only.
+ else
+ loop_count = 2;
+ }
+
+ // Create Disassembler Instance
+ lldb::DisassemblerSP disasm_sp(
+ Disassembler::FindPlugin(m_arch, nullptr, nullptr));
+
+ InstructionList instruction_list;
+ InstructionSP prev_insn;
+ bool prefer_file_cache = true; // Read from file
+ uint32_t inst_to_choose = 0;
+
+ Address addr = resolved_addr;
+
+ for (uint32_t i = 1; i <= loop_count; i++) {
+ // Adjust the address to read from.
+ addr.Slide(-2);
+ AddressRange range(addr, i * 2);
+ uint32_t insn_size = 0;
+
+ disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
+
+ uint32_t num_insns = disasm_sp->GetInstructionList().GetSize();
+ if (num_insns) {
+ prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0);
+ insn_size = prev_insn->GetOpcode().GetByteSize();
+ if (i == 1 && insn_size == 2) {
+ // This looks like a valid 2-byte instruction (but it could be a part
+ // of upper 4 byte instruction).
+ instruction_list.Append(prev_insn);
+ inst_to_choose = 1;
+ }
+ else if (i == 2) {
+ // Here we may get one 4-byte instruction or two 2-byte instructions.
+ if (num_insns == 2) {
+ // Looks like there are two 2-byte instructions above our
+ // breakpoint target address. Now the upper 2-byte instruction is
+ // either a valid 2-byte instruction or could be a part of it's
+ // upper 4-byte instruction. In both cases we don't care because in
+ // this case lower 2-byte instruction is definitely a valid
+ // instruction and whatever i=1 iteration has found out is true.
+ inst_to_choose = 1;
+ break;
+ }
+ else if (insn_size == 4) {
+ // This instruction claims its a valid 4-byte instruction. But it
+ // could be a part of it's upper 4-byte instruction. Lets try
+ // scanning upper 2 bytes to verify this.
+ instruction_list.Append(prev_insn);
+ inst_to_choose = 2;
+ }
+ }
+ else if (i == 3) {
+ if (insn_size == 4)
+ // FIXME: We reached here that means instruction at [target - 4] has
+ // already claimed to be a 4-byte instruction, and now instruction
+ // at [target - 6] is also claiming that it's a 4-byte instruction.
+ // This can not be true. In this case we can not decide the valid
+ // previous instruction so we let lldb set the breakpoint at the
+ // address given by user.
+ inst_to_choose = 0;
+ else
+ // This is straight-forward
+ inst_to_choose = 2;
+ break;
+ }
+ }
+ else {
+ // Decode failed, bytes do not form a valid instruction. So whatever
+ // previous iteration has found out is true.
+ if (i > 1) {
+ inst_to_choose = i - 1;
+ break;
+ }
+ }
+ }
+
+ // Check if we are able to find any valid instruction.
+ if (inst_to_choose) {
+ if (inst_to_choose > instruction_list.GetSize())
+ inst_to_choose--;
+ return instruction_list.GetInstructionAtIndex(inst_to_choose - 1).get();
+ }
+
+ return nullptr;
+}
diff --git a/source/Plugins/Architecture/Mips/ArchitectureMips.h b/source/Plugins/Architecture/Mips/ArchitectureMips.h
new file mode 100644
index 000000000000..2338daf2e468
--- /dev/null
+++ b/source/Plugins/Architecture/Mips/ArchitectureMips.h
@@ -0,0 +1,52 @@
+//===-- ArchitectureMips.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_MIPS_H
+#define LLDB_PLUGIN_ARCHITECTURE_MIPS_H
+
+#include "lldb/Core/Architecture.h"
+#include "lldb/Utility/ArchSpec.h"
+
+namespace lldb_private {
+
+class ArchitectureMips : public Architecture {
+public:
+ static ConstString GetPluginNameStatic();
+ static void Initialize();
+ static void Terminate();
+
+ ConstString GetPluginName() override;
+ uint32_t GetPluginVersion() override;
+
+ void OverrideStopInfo(Thread &thread) const override {}
+
+ lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr,
+ Target &) const override;
+
+ lldb::addr_t GetCallableLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
+ lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr,
+ AddressClass addr_class) const override;
+
+private:
+ Instruction *GetInstructionAtAddress(const ExecutionContext &exe_ctx,
+ const Address &resolved_addr,
+ lldb::addr_t symbol_offset) const;
+
+
+ static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+ ArchitectureMips(const ArchSpec &arch) : m_arch(arch) {}
+
+ ArchSpec m_arch;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_MIPS_H
diff --git a/source/Plugins/Architecture/Mips/CMakeLists.txt b/source/Plugins/Architecture/Mips/CMakeLists.txt
new file mode 100644
index 000000000000..9734edc6b12b
--- /dev/null
+++ b/source/Plugins/Architecture/Mips/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginArchitectureMips PLUGIN
+ ArchitectureMips.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbTarget
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 9b381dd3b96c..5df842250591 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Project includes
#include "DisassemblerLLVMC.h"
-// Other libraries and framework includes
#include "llvm-c/Disassembler.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -98,16 +94,15 @@ public:
bool DoesBranch() override {
if (m_does_branch == eLazyBoolCalculate) {
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
- disasm_sp->Lock(this, NULL);
+ DisassemblerScope disasm(*this);
+ if (disasm) {
DataExtractor data;
if (m_opcode.GetData(data)) {
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa);
+ GetDisasmToUse(is_alternate_isa, disasm);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst;
@@ -125,7 +120,6 @@ public:
m_does_branch = eLazyBoolNo;
}
}
- disasm_sp->Unlock();
}
}
return m_does_branch == eLazyBoolYes;
@@ -133,16 +127,15 @@ public:
bool HasDelaySlot() override {
if (m_has_delay_slot == eLazyBoolCalculate) {
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
- disasm_sp->Lock(this, NULL);
+ DisassemblerScope disasm(*this);
+ if (disasm) {
DataExtractor data;
if (m_opcode.GetData(data)) {
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa);
+ GetDisasmToUse(is_alternate_isa, disasm);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst;
@@ -160,27 +153,14 @@ public:
m_has_delay_slot = eLazyBoolNo;
}
}
- disasm_sp->Unlock();
}
}
return m_has_delay_slot == eLazyBoolYes;
}
DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) {
- is_alternate_isa = false;
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
- if (disasm_sp->m_alternate_disasm_up) {
- const AddressClass address_class = GetAddressClass();
-
- if (address_class == AddressClass::eCodeAlternateISA) {
- is_alternate_isa = true;
- return disasm_sp->m_alternate_disasm_up.get();
- }
- }
- return disasm_sp->m_disasm_up.get();
- }
- return nullptr;
+ DisassemblerScope disasm(*this);
+ return GetDisasmToUse(is_alternate_isa, disasm);
}
size_t Decode(const lldb_private::Disassembler &disassembler,
@@ -189,9 +169,9 @@ public:
// All we have to do is read the opcode which can be easy for some
// architectures
bool got_op = false;
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
- const ArchSpec &arch = disasm_sp->GetArchitecture();
+ DisassemblerScope disasm(*this);
+ if (disasm) {
+ const ArchSpec &arch = disasm->GetArchitecture();
const lldb::ByteOrder byte_order = data.GetByteOrder();
const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
@@ -232,7 +212,7 @@ public:
if (!got_op) {
bool is_alternate_isa = false;
DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa);
+ GetDisasmToUse(is_alternate_isa, disasm);
const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) {
@@ -261,10 +241,8 @@ public:
const addr_t pc = m_address.GetFileAddress();
llvm::MCInst inst;
- disasm_sp->Lock(this, NULL);
const size_t inst_size =
mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
- disasm_sp->Unlock();
if (inst_size == 0)
m_opcode.Clear();
else {
@@ -296,19 +274,19 @@ public:
std::string out_string;
std::string comment_string;
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
+ DisassemblerScope disasm(*this, exe_ctx);
+ if (disasm) {
DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr;
if (address_class == AddressClass::eCodeAlternateISA)
- mc_disasm_ptr = disasm_sp->m_alternate_disasm_up.get();
+ mc_disasm_ptr = disasm->m_alternate_disasm_up.get();
else
- mc_disasm_ptr = disasm_sp->m_disasm_up.get();
+ mc_disasm_ptr = disasm->m_disasm_up.get();
lldb::addr_t pc = m_address.GetFileAddress();
m_using_file_addr = true;
- const bool data_from_file = disasm_sp->m_data_from_file;
+ const bool data_from_file = disasm->m_data_from_file;
bool use_hex_immediates = true;
Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
@@ -328,8 +306,6 @@ public:
}
}
- disasm_sp->Lock(this, exe_ctx);
-
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst;
@@ -345,8 +321,6 @@ public:
}
}
- disasm_sp->Unlock();
-
if (inst_size == 0) {
m_comment.assign("unknown opcode");
inst_size = m_opcode.GetByteSize();
@@ -423,9 +397,27 @@ public:
bool UsingFileAddress() const { return m_using_file_addr; }
size_t GetByteSize() const { return m_opcode.GetByteSize(); }
- std::shared_ptr<DisassemblerLLVMC> GetDisassembler() {
- return m_disasm_wp.lock();
- }
+ /// Grants exclusive access to the disassembler and initializes it with the
+ /// given InstructionLLVMC and an optional ExecutionContext.
+ class DisassemblerScope {
+ std::shared_ptr<DisassemblerLLVMC> m_disasm;
+
+ public:
+ explicit DisassemblerScope(
+ InstructionLLVMC &i,
+ const lldb_private::ExecutionContext *exe_ctx = nullptr)
+ : m_disasm(i.m_disasm_wp.lock()) {
+ m_disasm->m_mutex.lock();
+ m_disasm->m_inst = &i;
+ m_disasm->m_exe_ctx = exe_ctx;
+ }
+ ~DisassemblerScope() { m_disasm->m_mutex.unlock(); }
+
+ /// Evaluates to true if this scope contains a valid disassembler.
+ operator bool() const { return static_cast<bool>(m_disasm); }
+
+ std::shared_ptr<DisassemblerLLVMC> operator->() { return m_disasm; }
+ };
static llvm::StringRef::const_iterator
ConsumeWhitespace(llvm::StringRef::const_iterator osi,
@@ -876,16 +868,15 @@ public:
bool IsCall() override {
if (m_is_call == eLazyBoolCalculate) {
- std::shared_ptr<DisassemblerLLVMC> disasm_sp(GetDisassembler());
- if (disasm_sp) {
- disasm_sp->Lock(this, NULL);
+ DisassemblerScope disasm(*this);
+ if (disasm) {
DataExtractor data;
if (m_opcode.GetData(data)) {
bool is_alternate_isa;
lldb::addr_t pc = m_address.GetFileAddress();
DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
- GetDisasmToUse(is_alternate_isa);
+ GetDisasmToUse(is_alternate_isa, disasm);
const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
llvm::MCInst inst;
@@ -900,7 +891,6 @@ public:
m_is_call = eLazyBoolNo;
}
}
- disasm_sp->Unlock();
}
}
return m_is_call == eLazyBoolYes;
@@ -913,6 +903,24 @@ protected:
LazyBool m_is_call;
bool m_is_valid;
bool m_using_file_addr;
+
+private:
+ DisassemblerLLVMC::MCDisasmInstance *
+ GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm) {
+ is_alternate_isa = false;
+ if (disasm) {
+ if (disasm->m_alternate_disasm_up) {
+ const AddressClass address_class = GetAddressClass();
+
+ if (address_class == AddressClass::eCodeAlternateISA) {
+ is_alternate_isa = true;
+ return disasm->m_alternate_disasm_up.get();
+ }
+ }
+ return disasm->m_disasm_up.get();
+ }
+ return nullptr;
+ }
};
std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>
@@ -1114,11 +1122,13 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
triple.getSubArch() == llvm::Triple::NoSubArch)
triple.setArchName("armv8.2a");
+ std::string features_str = "";
const char *triple_str = triple.getTriple().c_str();
// ARM Cortex M0-M7 devices only execute thumb instructions
if (arch.IsAlwaysThumbInstructions()) {
triple_str = thumb_arch.GetTriple().getTriple().c_str();
+ features_str += "+fp-armv8,";
}
const char *cpu = "";
@@ -1169,7 +1179,6 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
break;
}
- std::string features_str = "";
if (triple.getArch() == llvm::Triple::mips ||
triple.getArch() == llvm::Triple::mipsel ||
triple.getArch() == llvm::Triple::mips64 ||
@@ -1201,7 +1210,8 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch,
if (llvm_arch == llvm::Triple::arm) {
std::string thumb_triple(thumb_arch.GetTriple().getTriple());
m_alternate_disasm_up =
- MCDisasmInstance::Create(thumb_triple.c_str(), "", "", flavor, *this);
+ MCDisasmInstance::Create(thumb_triple.c_str(), "", features_str.c_str(),
+ flavor, *this);
if (!m_alternate_disasm_up)
m_disasm_up.reset();
@@ -1326,10 +1336,7 @@ bool DisassemblerLLVMC::FlavorValidForArchSpec(
if (triple.getArch() == llvm::Triple::x86 ||
triple.getArch() == llvm::Triple::x86_64) {
- if (strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0)
- return true;
- else
- return false;
+ return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0;
} else
return false;
}
@@ -1368,7 +1375,7 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
}
SymbolContext sym_ctx;
- const uint32_t resolve_scope =
+ const SymbolContextItem resolve_scope =
eSymbolContextFunction | eSymbolContextSymbol;
if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) {
pc_so_addr.GetModule()->ResolveSymbolContextForAddress(
diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
index b7e9ccb34701..8b9f7c37d2b8 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
@@ -10,13 +10,10 @@
#ifndef liblldb_DisassemblerLLVMC_h_
#define liblldb_DisassemblerLLVMC_h_
-// C Includes
-// C++ Includes
#include <memory>
#include <mutex>
#include <string>
-// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
@@ -77,19 +74,6 @@ protected:
uint64_t ReferencePC,
const char **ReferenceName);
- void Lock(InstructionLLVMC *inst,
- const lldb_private::ExecutionContext *exe_ctx) {
- m_mutex.lock();
- m_inst = inst;
- m_exe_ctx = exe_ctx;
- }
-
- void Unlock() {
- m_inst = NULL;
- m_exe_ctx = NULL;
- m_mutex.unlock();
- }
-
const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst;
std::mutex m_mutex;
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 8999000dff8c..3a80c68dd4d7 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -15,7 +15,6 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -29,6 +28,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "DynamicLoaderDarwinKernel.h"
@@ -58,7 +58,7 @@ enum KASLRScanType {
// range looking for a kernel
};
-OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
+static constexpr OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
{eKASLRScanNone, "none",
"Do not read memory looking for a Darwin kernel when attaching."},
{eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load "
@@ -68,17 +68,15 @@ OptionEnumValueElement g_kaslr_kernel_scan_enum_values[] = {
"the Darwin kernel's load address."},
{eKASLRScanExhaustiveScan, "exhaustive-scan",
"Scan through the entire potential address range of Darwin kernel (only "
- "on 32-bit targets)."},
- {0, NULL, NULL}};
+ "on 32-bit targets)."}};
-static PropertyDefinition g_properties[] = {
- {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, NULL,
+static constexpr PropertyDefinition g_properties[] = {
+ {"load-kexts", OptionValue::eTypeBoolean, true, true, NULL, {},
"Automatically loads kext images when attaching to a kernel."},
{"scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL,
- g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make "
- "while searching for a Darwin kernel on "
- "attach."},
- {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+ OptionEnumValues(g_kaslr_kernel_scan_enum_values),
+ "Control how many reads lldb will make while searching for a Darwin "
+ "kernel on attach."}};
enum { ePropertyLoadKexts, ePropertyScanType };
@@ -149,6 +147,7 @@ DynamicLoader *DynamicLoaderDarwinKernel::CreateInstance(Process *process,
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
if (triple_ref.getVendor() != llvm::Triple::Apple) {
return NULL;
}
@@ -212,13 +211,13 @@ DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr(Process *process) {
exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
return LLDB_INVALID_ADDRESS;
- if (!exe_objfile->GetHeaderAddress().IsValid())
+ if (!exe_objfile->GetBaseAddress().IsValid())
return LLDB_INVALID_ADDRESS;
if (CheckForKernelImageAtAddress(
- exe_objfile->GetHeaderAddress().GetFileAddress(), process) ==
+ exe_objfile->GetBaseAddress().GetFileAddress(), process) ==
exe_module->GetUUID())
- return exe_objfile->GetHeaderAddress().GetFileAddress();
+ return exe_objfile->GetBaseAddress().GetFileAddress();
return LLDB_INVALID_ADDRESS;
}
@@ -294,6 +293,18 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
return LLDB_INVALID_ADDRESS;
addr_t pc = thread->GetRegisterContext()->GetPC(LLDB_INVALID_ADDRESS);
+ // The kernel is always loaded in high memory, if the top bit is zero,
+ // this isn't a kernel.
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8) {
+ if ((pc & (1ULL << 63)) == 0) {
+ return LLDB_INVALID_ADDRESS;
+ }
+ } else {
+ if ((pc & (1ULL << 31)) == 0) {
+ return LLDB_INVALID_ADDRESS;
+ }
+ }
+
if (pc == LLDB_INVALID_ADDRESS)
return LLDB_INVALID_ADDRESS;
@@ -308,12 +319,13 @@ DynamicLoaderDarwinKernel::SearchForKernelNearPC(Process *process) {
// Search backwards 32 megabytes, looking for the start of the kernel at each
// one-megabyte boundary.
for (int i = 0; i < 32; i++, addr -= 0x100000) {
+ // x86_64 kernels are at offset 0
if (CheckForKernelImageAtAddress(addr, process).IsValid())
return addr;
+ // 32-bit arm kernels are at offset 0x1000 (one 4k page)
if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
return addr + 0x1000;
- if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
- return addr + 0x2000;
+ // 64-bit arm kernels are at offset 0x4000 (one 16k page)
if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
return addr + 0x4000;
}
@@ -352,12 +364,13 @@ lldb::addr_t DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch(
addr_t addr = kernel_range_low;
while (addr >= kernel_range_low && addr < kernel_range_high) {
+ // x86_64 kernels are at offset 0
if (CheckForKernelImageAtAddress(addr, process).IsValid())
return addr;
+ // 32-bit arm kernels are at offset 0x1000 (one 4k page)
if (CheckForKernelImageAtAddress(addr + 0x1000, process).IsValid())
return addr + 0x1000;
- if (CheckForKernelImageAtAddress(addr + 0x2000, process).IsValid())
- return addr + 0x2000;
+ // 64-bit arm kernels are at offset 0x4000 (one 16k page)
if (CheckForKernelImageAtAddress(addr + 0x4000, process).IsValid())
return addr + 0x4000;
addr += 0x100000;
@@ -388,8 +401,8 @@ DynamicLoaderDarwinKernel::ReadMachHeader(addr_t addr, Process *process, llvm::M
if (::memcmp (&header.magic, &magicks[i], sizeof (uint32_t)) == 0)
found_matching_pattern = true;
- if (found_matching_pattern == false)
- return false;
+ if (!found_matching_pattern)
+ return false;
if (header.magic == llvm::MachO::MH_CIGAM ||
header.magic == llvm::MachO::MH_CIGAM_64) {
@@ -425,7 +438,7 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
llvm::MachO::mach_header header;
- if (ReadMachHeader (addr, process, header) == false)
+ if (!ReadMachHeader(addr, process, header))
return UUID();
// First try a quick test -- read the first 4 bytes and see if there is a
@@ -436,8 +449,8 @@ DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress(lldb::addr_t addr,
if (header.filetype == llvm::MachO::MH_EXECUTE &&
(header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
// Create a full module to get the UUID
- ModuleSP memory_module_sp = process->ReadModuleFromMemory(
- FileSpec("temp_mach_kernel", false), addr);
+ ModuleSP memory_module_sp =
+ process->ReadModuleFromMemory(FileSpec("temp_mach_kernel"), addr);
if (!memory_module_sp.get())
return UUID();
@@ -605,16 +618,10 @@ void DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId(
bool DynamicLoaderDarwinKernel::KextImageInfo::
operator==(const KextImageInfo &rhs) {
if (m_uuid.IsValid() || rhs.GetUUID().IsValid()) {
- if (m_uuid == rhs.GetUUID()) {
- return true;
- }
- return false;
+ return m_uuid == rhs.GetUUID();
}
- if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
- return true;
-
- return false;
+ return m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress();
}
void DynamicLoaderDarwinKernel::KextImageInfo::SetName(const char *name) {
@@ -647,16 +654,16 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
if (m_load_address == LLDB_INVALID_ADDRESS)
return false;
- FileSpec file_spec;
- file_spec.SetFile(m_name.c_str(), false, FileSpec::Style::native);
+ FileSpec file_spec(m_name.c_str());
llvm::MachO::mach_header mh;
size_t size_to_read = 512;
- if (ReadMachHeader (m_load_address, process, mh)) {
- if (mh.magic == llvm::MachO::MH_CIGAM || llvm::MachO::MH_MAGIC)
- size_to_read = sizeof (llvm::MachO::mach_header) + mh.sizeofcmds;
- if (mh.magic == llvm::MachO::MH_CIGAM_64 || llvm::MachO::MH_MAGIC_64)
- size_to_read = sizeof (llvm::MachO::mach_header_64) + mh.sizeofcmds;
+ if (ReadMachHeader(m_load_address, process, mh)) {
+ if (mh.magic == llvm::MachO::MH_CIGAM || mh.magic == llvm::MachO::MH_MAGIC)
+ size_to_read = sizeof(llvm::MachO::mach_header) + mh.sizeofcmds;
+ if (mh.magic == llvm::MachO::MH_CIGAM_64 ||
+ mh.magic == llvm::MachO::MH_MAGIC_64)
+ size_to_read = sizeof(llvm::MachO::mach_header_64) + mh.sizeofcmds;
}
ModuleSP memory_module_sp =
@@ -732,7 +739,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule(
}
bool DynamicLoaderDarwinKernel::KextImageInfo::IsKernel() const {
- return m_kernel_image == true;
+ return m_kernel_image;
}
void DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel(bool is_kernel) {
@@ -784,7 +791,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
// to do anything useful. This will force a clal to
if (IsKernel()) {
if (Symbols::DownloadObjectAndSymbolFile(module_spec, true)) {
- if (module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
m_module_sp.reset(new Module(module_spec.GetFileSpec(),
target.GetArchitecture()));
if (m_module_sp.get() &&
@@ -807,7 +814,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
PlatformDarwinKernel::GetPluginNameStatic());
if (platform_name == g_platform_name) {
ModuleSpec kext_bundle_module_spec(module_spec);
- FileSpec kext_filespec(m_name.c_str(), false);
+ FileSpec kext_filespec(m_name.c_str());
kext_bundle_module_spec.GetFileSpec() = kext_filespec;
platform_sp->GetSharedModule(
kext_bundle_module_spec, process, m_module_sp,
@@ -847,7 +854,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
target.GetImages().AppendIfNeeded(m_module_sp);
if (IsKernel() &&
target.GetExecutableModulePointer() != m_module_sp.get()) {
- target.SetExecutableModule(m_module_sp, false);
+ target.SetExecutableModule(m_module_sp, eLoadDependentsNo);
}
}
}
@@ -932,7 +939,7 @@ bool DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule(
ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
if (kernel_object_file) {
addr_t file_address =
- kernel_object_file->GetHeaderAddress().GetFileAddress();
+ kernel_object_file->GetBaseAddress().GetFileAddress();
if (m_load_address != LLDB_INVALID_ADDRESS &&
file_address != LLDB_INVALID_ADDRESS) {
s->Printf("Kernel slid 0x%" PRIx64 " in memory.\n",
@@ -1006,10 +1013,10 @@ void DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded() {
ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
if (kernel_object_file) {
addr_t load_address =
- kernel_object_file->GetHeaderAddress().GetLoadAddress(
+ kernel_object_file->GetBaseAddress().GetLoadAddress(
&m_process->GetTarget());
addr_t file_address =
- kernel_object_file->GetHeaderAddress().GetFileAddress();
+ kernel_object_file->GetBaseAddress().GetFileAddress();
if (load_address != LLDB_INVALID_ADDRESS && load_address != 0) {
m_kernel.SetLoadAddress(load_address);
if (load_address != file_address) {
@@ -1281,7 +1288,7 @@ bool DynamicLoaderDarwinKernel::ParseKextSummaries(
const uint32_t num_of_new_kexts = kext_summaries.size();
for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++) {
- if (to_be_added[new_kext] == true) {
+ if (to_be_added[new_kext]) {
KextImageInfo &image_info = kext_summaries[new_kext];
if (load_kexts) {
if (!image_info.LoadImageUsingMemoryModule(m_process)) {
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index 75998f1cc3be..7aacebd9b50f 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -10,17 +10,13 @@
#ifndef liblldb_DynamicLoaderDarwinKernel_h_
#define liblldb_DynamicLoaderDarwinKernel_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <string>
#include <vector>
-// Other libraries and framework includes
-#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Host/SafeMachO.h"
-// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 5ca20229d018..81eab8fdd970 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -179,7 +176,7 @@ ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
return executable;
// The target executable file does not exits
- if (!executable->GetFileSpec().Exists())
+ if (!FileSystem::Instance().Exists(executable->GetFileSpec()))
return executable;
// Prep module for loading
@@ -205,8 +202,7 @@ ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() {
if (executable.get() != target.GetExecutableModulePointer()) {
// Don't load dependent images since we are in dyld where we will know and
// find out about all images that are loaded
- const bool get_dependent_images = false;
- target.SetExecutableModule(executable, get_dependent_images);
+ target.SetExecutableModule(executable, eLoadDependentsNo);
}
return executable;
@@ -368,7 +364,8 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
E = m_rendezvous.loaded_end();
for (I = m_rendezvous.loaded_begin(); I != E; ++I) {
- FileSpec file(I->path, true);
+ FileSpec file(I->path);
+ FileSystem::Instance().Resolve(file);
ModuleSP module_sp =
LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
if (module_sp.get()) {
@@ -392,7 +389,8 @@ void DynamicLoaderHexagonDYLD::RefreshModules() {
E = m_rendezvous.unloaded_end();
for (I = m_rendezvous.unloaded_begin(); I != E; ++I) {
- FileSpec file(I->path, true);
+ FileSpec file(I->path);
+ FileSystem::Instance().Resolve(file);
ModuleSpec module_spec(file);
ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec);
@@ -455,7 +453,7 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread,
AddressVector::iterator start = addrs.begin();
AddressVector::iterator end = addrs.end();
- std::sort(start, end);
+ llvm::sort(start, end);
addrs.erase(std::unique(start, end), end);
thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
}
@@ -486,7 +484,7 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() {
for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
const char *module_path = I->path.c_str();
- FileSpec file(module_path, false);
+ FileSpec file(module_path);
ModuleSP module_sp =
LoadModuleAtAddress(file, I->link_addr, I->base_addr, true);
if (module_sp.get()) {
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
index 200a4171bd1c..d39f14e8b3fb 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h
@@ -10,10 +10,6 @@
#ifndef liblldb_DynamicLoaderHexagonDYLD_h_
#define liblldb_DynamicLoaderHexagonDYLD_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Target/DynamicLoader.h"
diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
index bdf6bae75197..758f358dc618 100644
--- a/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
@@ -10,14 +10,11 @@
#ifndef liblldb_HexagonDYLDRendezvous_H_
#define liblldb_HexagonDYLDRendezvous_H_
-// C Includes
-#include <limits.h> // for PATH_MAX
-// C++ Includes
+#include <limits.h>
#include <list>
#include <map>
#include <string>
-// Other libraries and framework includes
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index c6439a30c8a3..944be9633e00 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -15,7 +15,6 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -32,6 +31,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
#ifdef ENABLE_DEBUG_PRINTF
@@ -115,7 +115,7 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
// No UUID, we must rely upon the cached module modification time and the
// modification time of the file on disk
if (module_sp->GetModificationTime() !=
- FileSystem::GetModificationTime(module_sp->GetFileSpec()))
+ FileSystem::Instance().GetModificationTime(module_sp->GetFileSpec()))
module_sp.reset();
}
@@ -359,22 +359,24 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
return false;
StructuredData::Dictionary *image = image_sp->GetAsDictionary();
- if (image->HasKey("load_address") == false ||
- image->HasKey("pathname") == false ||
- image->HasKey("mod_date") == false ||
- image->HasKey("mach_header") == false ||
+ // clang-format off
+ if (!image->HasKey("load_address") ||
+ !image->HasKey("pathname") ||
+ !image->HasKey("mod_date") ||
+ !image->HasKey("mach_header") ||
image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr ||
- image->HasKey("segments") == false ||
+ !image->HasKey("segments") ||
image->GetValueForKey("segments")->GetAsArray() == nullptr ||
- image->HasKey("uuid") == false) {
+ !image->HasKey("uuid")) {
return false;
}
+ // clang-format on
image_infos[i].address =
image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
image_infos[i].mod_date =
image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
image_infos[i].file_spec.SetFile(
- image->GetValueForKey("pathname")->GetAsString()->GetValue(), false,
+ image->GetValueForKey("pathname")->GetAsString()->GetValue(),
FileSpec::Style::native);
StructuredData::Dictionary *mh =
@@ -400,6 +402,8 @@ bool DynamicLoaderDarwin::JSONImageInformationIntoImageInfo(
image_infos[i].os_type = llvm::Triple::TvOS;
else if (os_name == "watchos")
image_infos[i].os_type = llvm::Triple::WatchOS;
+ // NEED_BRIDGEOS_TRIPLE else if (os_name == "bridgeos")
+ // NEED_BRIDGEOS_TRIPLE image_infos[i].os_type = llvm::Triple::BridgeOS;
}
if (image->HasKey("min_version_os_sdk")) {
image_infos[i].min_version_os_sdk =
@@ -513,11 +517,12 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
const size_t image_infos_size = image_infos.size();
for (size_t i = 0; i < image_infos_size; i++) {
if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER) {
- // In a "simulator" process (an x86 process that is ios/tvos/watchos) we
- // will have two dyld modules -- a "dyld" that we want to keep track of,
- // and a "dyld_sim" which we don't need to keep track of here. If the
- // target is an x86 system and the OS of the dyld binary is
- // ios/tvos/watchos, then we are looking at dyld_sym.
+ // In a "simulator" process (an x86 process that is
+ // ios/tvos/watchos/bridgeos) we will have two dyld modules --
+ // a "dyld" that we want to keep track of, and a "dyld_sim" which
+ // we don't need to keep track of here. If the target is an x86
+ // system and the OS of the dyld binary is ios/tvos/watchos/bridgeos,
+ // then we are looking at dyld_sym.
// debugserver has only recently (late 2016) started sending up the os
// type for each binary it sees -- so if we don't have an os type, use a
@@ -531,6 +536,7 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
if (image_infos[i].os_type != llvm::Triple::OSType::IOS &&
image_infos[i].os_type != llvm::Triple::TvOS &&
image_infos[i].os_type != llvm::Triple::WatchOS) {
+ // NEED_BRIDGEOS_TRIPLE image_infos[i].os_type != llvm::Triple::BridgeOS) {
dyld_idx = i;
}
}
@@ -555,8 +561,7 @@ void DynamicLoaderDarwin::UpdateSpecialBinariesFromNewImageInfos(
target.GetImages().AppendIfNeeded(exe_module_sp);
UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]);
if (exe_module_sp.get() != target.GetExecutableModulePointer()) {
- const bool get_dependent_images = false;
- target.SetExecutableModule(exe_module_sp, get_dependent_images);
+ target.SetExecutableModule(exe_module_sp, eLoadDependentsNo);
}
}
}
@@ -709,11 +714,7 @@ bool DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo(SymbolContext &sym_ctx) {
return false;
ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp)) {
- return true;
- }
-
- return false;
+ return objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary(module_sp);
}
//----------------------------------------------------------------------
@@ -1124,6 +1125,10 @@ bool DynamicLoaderDarwin::UseDYLDSPI(Process *process) {
// watchOS 3 and newer
if (os_type == llvm::Triple::WatchOS && version >= llvm::VersionTuple(3))
use_new_spi_interface = true;
+
+ // NEED_BRIDGEOS_TRIPLE // Any BridgeOS
+ // NEED_BRIDGEOS_TRIPLE if (os_type == llvm::Triple::BridgeOS)
+ // NEED_BRIDGEOS_TRIPLE use_new_spi_interface = true;
}
if (log) {
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
index a02d1ad9bee3..690253ba5ff2 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
@@ -10,18 +10,14 @@
#ifndef liblldb_DynamicLoaderDarwin_h_
#define liblldb_DynamicLoaderDarwin_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UUID.h"
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 4a8ad38d1785..1ff0ec2c7937 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -12,7 +12,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
@@ -21,6 +20,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "DynamicLoaderDarwin.h"
#include "DynamicLoaderMacOS.h"
@@ -55,6 +55,7 @@ DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
create = triple_ref.getVendor() == llvm::Triple::Apple;
break;
default:
@@ -64,7 +65,7 @@ DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
}
}
- if (UseDYLDSPI(process) == false) {
+ if (!UseDYLDSPI(process)) {
create = false;
}
@@ -78,7 +79,8 @@ DynamicLoader *DynamicLoaderMacOS::CreateInstance(Process *process,
//----------------------------------------------------------------------
DynamicLoaderMacOS::DynamicLoaderMacOS(Process *process)
: DynamicLoaderDarwin(process), m_image_infos_stop_id(UINT32_MAX),
- m_break_id(LLDB_INVALID_BREAK_ID), m_mutex() {}
+ m_break_id(LLDB_INVALID_BREAK_ID), m_mutex(),
+ m_maybe_image_infos_address(LLDB_INVALID_ADDRESS) {}
//----------------------------------------------------------------------
// Destructor
@@ -94,16 +96,31 @@ bool DynamicLoaderMacOS::ProcessDidExec() {
if (m_process) {
// If we are stopped after an exec, we will have only one thread...
if (m_process->GetThreadList().GetSize() == 1) {
- // See if we are stopped at '_dyld_start'
- ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
- if (thread_sp) {
- lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
- if (frame_sp) {
- const Symbol *symbol =
- frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
- if (symbol) {
- if (symbol->GetName() == ConstString("_dyld_start"))
- did_exec = true;
+ // Maybe we still have an image infos address around? If so see
+ // if that has changed, and if so we have exec'ed.
+ if (m_maybe_image_infos_address != LLDB_INVALID_ADDRESS) {
+ lldb::addr_t image_infos_address = m_process->GetImageInfoAddress();
+ if (image_infos_address != m_maybe_image_infos_address) {
+ // We don't really have to reset this here, since we are going to
+ // call DoInitialImageFetch right away to handle the exec. But in
+ // case anybody looks at it in the meantime, it can't hurt.
+ m_maybe_image_infos_address = image_infos_address;
+ did_exec = true;
+ }
+ }
+
+ if (!did_exec) {
+ // See if we are stopped at '_dyld_start'
+ ThreadSP thread_sp(m_process->GetThreadList().GetThreadAtIndex(0));
+ if (thread_sp) {
+ lldb::StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
+ if (frame_sp) {
+ const Symbol *symbol =
+ frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol) {
+ if (symbol->GetName() == ConstString("_dyld_start"))
+ did_exec = true;
+ }
}
}
}
@@ -179,6 +196,7 @@ void DynamicLoaderMacOS::DoInitialImageFetch() {
}
m_dyld_image_infos_stop_id = m_process->GetStopID();
+ m_maybe_image_infos_address = m_process->GetImageInfoAddress();
}
bool DynamicLoaderMacOS::NeedToDoInitialImageFetch() { return true; }
@@ -485,8 +503,7 @@ bool DynamicLoaderMacOS::GetSharedCacheInformation(
info_dict->GetValueForKey("shared_cache_uuid")->GetStringValue();
if (!uuid_str.empty())
uuid.SetFromStringRef(uuid_str);
- if (info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue() ==
- false)
+ if (!info_dict->GetValueForKey("no_shared_cache")->GetBooleanValue())
using_shared_cache = eLazyBoolYes;
else
using_shared_cache = eLazyBoolNo;
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
index db90966e5615..6303c066511c 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
-// watchOS)
+// watchOS / BridgeOS)
// platforms late 2016 and newer, where lldb will call dyld SPI functions to get
// information about shared libraries, information about the shared cache, and
// the _dyld_debugger_notification function we put a breakpoint on give us an
@@ -18,17 +18,12 @@
#ifndef liblldb_DynamicLoaderMacOS_h_
#define liblldb_DynamicLoaderMacOS_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UUID.h"
@@ -109,6 +104,12 @@ protected:
// loaded/unloaded images
lldb::user_id_t m_break_id;
mutable std::recursive_mutex m_mutex;
+ lldb::addr_t m_maybe_image_infos_address; // If dyld is still maintaining the
+ // all_image_infos address, store it
+ // here so we can use it to detect
+ // exec's when talking to
+ // debugservers that don't support
+ // the "reason:exec" annotation.
private:
DISALLOW_COPY_AND_ASSIGN(DynamicLoaderMacOS);
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 265f19d0ca06..ec459a783f94 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -13,7 +13,6 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -27,6 +26,7 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "DynamicLoaderDarwin.h"
#include "DynamicLoaderMacOSXDYLD.h"
@@ -75,6 +75,7 @@ DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
create = triple_ref.getVendor() == llvm::Triple::Apple;
break;
default:
@@ -84,7 +85,7 @@ DynamicLoader *DynamicLoaderMacOSXDYLD::CreateInstance(Process *process,
}
}
- if (UseDYLDSPI(process) == true) {
+ if (UseDYLDSPI(process)) {
create = false;
}
@@ -121,12 +122,12 @@ bool DynamicLoaderMacOSXDYLD::ProcessDidExec() {
// value differs from the Process' image info address. When a process
// execs itself it might cause a change if ASLR is enabled.
const addr_t shlib_addr = m_process->GetImageInfoAddress();
- if (m_process_image_addr_is_all_images_infos == true &&
+ if (m_process_image_addr_is_all_images_infos &&
shlib_addr != m_dyld_all_image_infos_addr) {
// The image info address from the process is the
// 'dyld_all_image_infos' address and it has changed.
did_exec = true;
- } else if (m_process_image_addr_is_all_images_infos == false &&
+ } else if (!m_process_image_addr_is_all_images_infos &&
shlib_addr == m_dyld.address) {
// The image info address from the process is the mach_header address
// for dyld and it has changed.
@@ -692,9 +693,7 @@ bool DynamicLoaderMacOSXDYLD::ReadImageInfos(
error);
// don't resolve the path
if (error.Success()) {
- const bool resolve_path = false;
- image_infos[i].file_spec.SetFile(raw_path, resolve_path,
- FileSpec::Style::native);
+ image_infos[i].file_spec.SetFile(raw_path, FileSpec::Style::native);
}
}
return true;
@@ -893,7 +892,8 @@ uint32_t DynamicLoaderMacOSXDYLD::ParseLoadCommands(const DataExtractor &data,
const lldb::offset_t name_offset =
load_cmd_offset + data.GetU32(&offset);
const char *path = data.PeekCStr(name_offset);
- lc_id_dylinker->SetFile(path, true, FileSpec::Style::native);
+ lc_id_dylinker->SetFile(path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(*lc_id_dylinker);
}
break;
@@ -975,9 +975,8 @@ void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(
// re-add it back to make sure it is always in the list.
ModuleSP dyld_module_sp(GetDYLDModule());
- const bool get_dependent_images = false;
m_process->GetTarget().SetExecutableModule(exe_module_sp,
- get_dependent_images);
+ eLoadDependentsNo);
if (dyld_module_sp) {
if (target.GetImages().AppendIfNeeded(dyld_module_sp)) {
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 8b5052e4e230..3dc0f15bddf7 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
// This is the DynamicLoader plugin for Darwin (macOS / iPhoneOS / tvOS /
-// watchOS)
+// watchOS / BridgeOS)
// platforms earlier than 2016, where lldb would read the "dyld_all_image_infos"
// dyld internal structure to understand where things were loaded and the
// solib loaded/unloaded notification function we put a breakpoint on gives us
@@ -21,17 +21,13 @@
#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
#define liblldb_DynamicLoaderMacOSXDYLD_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UUID.h"
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
index 7dd2b57da0cb..8068795df53a 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
@@ -100,7 +100,7 @@ const char *AuxVector::GetEntryName(EntryType type) {
#define ENTRY_NAME(_type) \
_type: \
- name = #_type + 5
+ name = &#_type[5]
switch (type) {
case ENTRY_NAME(AUXV_AT_NULL); break;
case ENTRY_NAME(AUXV_AT_IGNORE); break;
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
index 3b06fe18f0c6..25446e33afd4 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -10,11 +10,8 @@
#ifndef liblldb_AuxVector_H_
#define liblldb_AuxVector_H_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "lldb/lldb-forward.h"
namespace lldb_private {
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index b1513b51a90a..b30a1ab2cf1f 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -243,7 +243,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo(
entry.base_addr = base_addr;
entry.dyn_addr = dyn_addr;
- entry.file_spec.SetFile(name, false, FileSpec::Style::native);
+ entry.file_spec.SetFile(name, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, name);
@@ -455,14 +455,10 @@ static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) {
// On Android L (API 21, 22) the load address of the "/system/bin/linker"
// isn't filled in correctly.
unsigned os_major = target.GetPlatform()->GetOSVersion().getMajor();
- if (target.GetArchitecture().GetTriple().isAndroid() &&
- (os_major == 21 || os_major == 22) &&
- (file_path == "/system/bin/linker" ||
- file_path == "/system/bin/linker64")) {
- return true;
- }
-
- return false;
+ return target.GetArchitecture().GetTriple().isAndroid() &&
+ (os_major == 21 || os_major == 22) &&
+ (file_path == "/system/bin/linker" ||
+ file_path == "/system/bin/linker64");
}
void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry,
@@ -517,7 +513,7 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) {
return false;
std::string file_path = ReadStringFromMemory(entry.path_addr);
- entry.file_spec.SetFile(file_path, false, FileSpec::Style::native);
+ entry.file_spec.SetFile(file_path, FileSpec::Style::native);
UpdateBaseAddrIfNecessary(entry, file_path);
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
index a7071801f569..f1a62c3bf9d8 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -10,12 +10,9 @@
#ifndef liblldb_Rendezvous_H_
#define liblldb_Rendezvous_H_
-// C Includes
-// C++ Includes
#include <list>
#include <string>
-// Other libraries and framework includes
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 26825d879f04..6774b4fd1291 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -10,10 +10,8 @@
// Main header include
#include "DynamicLoaderPOSIXDYLD.h"
-// Project includes
#include "AuxVector.h"
-// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -29,8 +27,6 @@
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Utility/Log.h"
-// C++ Includes
-// C Includes
using namespace lldb;
using namespace lldb_private;
@@ -121,7 +117,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() {
EvalSpecialModulesStatus();
// if we dont have a load address we cant re-base
- bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
+ bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS;
// if we have a valid executable
if (executable_sp.get()) {
@@ -500,7 +496,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
AddressVector::iterator start = addrs.begin();
AddressVector::iterator end = addrs.end();
- std::sort(start, end);
+ llvm::sort(start, end);
addrs.erase(std::unique(start, end), end);
thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
}
@@ -512,7 +508,7 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() {
if (m_vdso_base == LLDB_INVALID_ADDRESS)
return;
- FileSpec file("[vdso]", false);
+ FileSpec file("[vdso]");
MemoryRegionInfo info;
Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info);
@@ -543,7 +539,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
return nullptr;
}
- FileSpec file(info.GetName().GetCString(), false);
+ FileSpec file(info.GetName().GetCString());
ModuleSpec module_spec(file, target.GetArchitecture());
if (ModuleSP module_sp = target.GetSharedModule(module_spec)) {
@@ -756,7 +752,7 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule(
return;
}
- target.SetExecutableModule(module_sp, false);
+ target.SetExecutableModule(module_sp, eLoadDependentsNo);
}
bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo(
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
index 0456baf4a658..c5f2d3bcffbc 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -10,13 +10,9 @@
#ifndef liblldb_DynamicLoaderPOSIXDYLD_h_
#define liblldb_DynamicLoaderPOSIXDYLD_h_
-// C Includes
-// C++ Includes
#include <map>
#include <memory>
-// Other libraries and framework includes
-// Project includes
#include "DYLDRendezvous.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/ModuleList.h"
diff --git a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
index 2d18ec86afd3..7f8f82c76f72 100644
--- a/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
+++ b/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h
@@ -10,10 +10,6 @@
#ifndef liblldb_DynamicLoaderStatic_h_
#define liblldb_DynamicLoaderStatic_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 6502d7a7a58c..9405b1a5cfdc 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -10,12 +10,14 @@
#include "DynamicLoaderWindowsDYLD.h"
+#include "lldb/Core/Module.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 "lldb/Utility/Log.h"
#include "llvm/ADT/Triple.h"
@@ -60,7 +62,39 @@ DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
return nullptr;
}
-void DynamicLoaderWindowsDYLD::DidAttach() {}
+void DynamicLoaderWindowsDYLD::DidAttach() {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__);
+
+ ModuleSP executable = GetTargetExecutable();
+
+ if (!executable.get())
+ return;
+
+ // Try to fetch the load address of the file from the process, since there
+ // could be randomization of the load address.
+
+ // It might happen that the remote has a different dir for the file, so we
+ // only send the basename of the executable in the query. I think this is safe
+ // because I doubt that two executables with the same basenames are loaded in
+ // memory...
+ FileSpec file_spec(
+ executable->GetPlatformFileSpec().GetFilename().GetCString());
+ bool is_loaded;
+ addr_t base_addr = 0;
+ lldb::addr_t load_addr;
+ Status error = m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
+ if (error.Success() && is_loaded) {
+ base_addr = load_addr;
+ UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, base_addr, false);
+ }
+
+ ModuleList module_list;
+ module_list.Append(executable);
+ m_process->GetTarget().ModulesDidLoad(module_list);
+ m_process->LoadModules();
+}
void DynamicLoaderWindowsDYLD::DidLaunch() {}
diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index de6e295f7891..342b32b10927 100644
--- a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -10,10 +10,6 @@
#ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_
#define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/DynamicLoader.h"
#include "lldb/lldb-forward.h"
diff --git a/source/Plugins/ExpressionParser/CMakeLists.txt b/source/Plugins/ExpressionParser/CMakeLists.txt
index dc0540ad30a1..17c40aee44cc 100644
--- a/source/Plugins/ExpressionParser/CMakeLists.txt
+++ b/source/Plugins/ExpressionParser/CMakeLists.txt
@@ -1,2 +1 @@
add_subdirectory(Clang)
-add_subdirectory(Go)
diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
index fa49a51f32a6..c2bc18a04e95 100644
--- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp
@@ -87,7 +87,8 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) {
SynthesizeObjCMethodResult(method_decl);
}
} else if (FunctionDecl *function_decl = dyn_cast<FunctionDecl>(D)) {
- if (m_ast_context &&
+ // When completing user input the body of the function may be a nullptr.
+ if (m_ast_context && function_decl->hasBody() &&
!function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) {
RecordPersistentTypes(function_decl);
SynthesizeFunctionResult(function_decl);
diff --git a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index d98a2b25fbb7..84771e59531d 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -332,11 +332,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
TypeList types;
- SymbolContext null_sc;
ConstString name(tag_decl->getName().str().c_str());
- i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX,
- types);
+ i->first->FindTypesInNamespace(name, &i->second, UINT32_MAX, types);
for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
lldb::TypeSP type = types.GetTypeAtIndex(ti);
@@ -366,7 +364,6 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
} else {
TypeList types;
- SymbolContext null_sc;
ConstString name(tag_decl->getName().str().c_str());
CompilerDeclContext namespace_decl;
@@ -374,7 +371,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
bool exact_match = false;
llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes(null_sc, name, exact_match, UINT32_MAX,
+ module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
searched_symbol_files, types);
for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) {
@@ -771,18 +768,16 @@ bool ClangASTSource::IgnoreName(const ConstString name,
static const ConstString id_name("id");
static const ConstString Class_name("Class");
- if (name == id_name || name == Class_name)
- return true;
+ if (m_ast_context->getLangOpts().ObjC)
+ 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;
+ return name_string_ref.empty() ||
+ (ignore_all_dollar_names && name_string_ref.startswith("$")) ||
+ name_string_ref.startswith("_$");
}
void ClangASTSource::FindExternalVisibleDecls(
@@ -804,10 +799,8 @@ void ClangASTSource::FindExternalVisibleDecls(
SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
if (symbol_vendor) {
- SymbolContext null_sc;
-
found_namespace_decl =
- symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ symbol_vendor->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
@@ -837,10 +830,8 @@ void ClangASTSource::FindExternalVisibleDecls(
if (!symbol_vendor)
continue;
- SymbolContext null_sc;
-
found_namespace_decl =
- symbol_vendor->FindNamespace(null_sc, name, &namespace_decl);
+ symbol_vendor->FindNamespace(name, &namespace_decl);
if (found_namespace_decl) {
context.m_namespace_map->push_back(
@@ -860,15 +851,12 @@ void ClangASTSource::FindExternalVisibleDecls(
break;
TypeList types;
- SymbolContext null_sc;
const bool exact_match = true;
llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types);
+ module_sp->FindTypesInNamespace(name, &namespace_decl, 1, types);
else {
- SymbolContext sc;
- sc.module_sp = module_sp;
- m_target->GetImages().FindTypes(sc, name, exact_match, 1,
+ m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
searched_symbol_files, types);
}
@@ -1655,10 +1643,10 @@ static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
std::vector<PairType> sorted_items;
sorted_items.reserve(source_map.size());
sorted_items.assign(source_map.begin(), source_map.end());
- std::sort(sorted_items.begin(), sorted_items.end(),
- [](const PairType &lhs, const PairType &rhs) {
- return lhs.second < rhs.second;
- });
+ llvm::sort(sorted_items.begin(), sorted_items.end(),
+ [](const PairType &lhs, const PairType &rhs) {
+ return lhs.second < rhs.second;
+ });
for (const auto &item : sorted_items) {
DeclFromUser<D> user_decl(const_cast<D *>(item.first));
@@ -1883,10 +1871,8 @@ void ClangASTSource::CompleteNamespaceMap(
if (!symbol_vendor)
continue;
- SymbolContext null_sc;
-
- found_namespace_decl = symbol_vendor->FindNamespace(
- null_sc, name, &module_parent_namespace_decl);
+ found_namespace_decl =
+ symbol_vendor->FindNamespace(name, &module_parent_namespace_decl);
if (!found_namespace_decl)
continue;
@@ -1918,10 +1904,8 @@ void ClangASTSource::CompleteNamespaceMap(
if (!symbol_vendor)
continue;
- SymbolContext null_sc;
-
found_namespace_decl =
- symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl);
+ symbol_vendor->FindNamespace(name, &null_namespace_decl);
if (!found_namespace_decl)
continue;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 0811a7999920..9c2f8c4b6c92 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -17,7 +17,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/Materializer.h"
@@ -44,6 +43,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private.h"
#include "clang/AST/ASTConsumer.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
index b67387930190..93fa57876bce 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h
@@ -10,18 +10,14 @@
#ifndef liblldb_ClangExpressionDeclMap_h_
#define liblldb_ClangExpressionDeclMap_h_
-// C Includes
#include <signal.h>
#include <stdint.h>
-// C++ Includes
#include <vector>
#include "ClangASTSource.h"
#include "ClangExpressionVariable.h"
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/Materializer.h"
@@ -325,12 +321,6 @@ public:
/// @param[in] namespace_decl
/// If valid and module is non-NULL, the parent namespace.
///
- /// @param[in] name
- /// The name as a plain C string. The NameSearchContext contains
- /// a DeclarationName for the name so at first the name may seem
- /// redundant, but ClangExpressionDeclMap operates in RTTI land so
- /// it can't access DeclarationName.
- ///
/// @param[in] current_id
/// The ID for the current FindExternalVisibleDecls invocation,
/// for logging purposes.
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
index e0d3ace15bd1..b5b640c9185f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h
@@ -10,14 +10,10 @@
#ifndef liblldb_ClangExpression_h_
#define liblldb_ClangExpression_h_
-// C Includes
-// C++ Includes
#include <map>
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/ClangForward.h"
#include "lldb/Expression/ExpressionTypeSystemHelper.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index c5406fcc3340..6650c0db967f 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -7,12 +7,11 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
+#include <cctype>
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/PrettyPrinter.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
@@ -34,6 +33,8 @@
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaConsumer.h"
#include "llvm/ADT/StringRef.h"
@@ -55,7 +56,6 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
-// Project includes
#include "ClangDiagnostic.h"
#include "ClangExpressionParser.h"
@@ -222,7 +222,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
Expression &expr,
bool generate_debug_info)
: ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(),
- m_code_generator(), m_pp_callbacks(nullptr) {
+ m_pp_callbacks(nullptr) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
// We can't compile expressions without a target. So if the exe_scope is
@@ -377,8 +377,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
m_compiler->getLangOpts().CPlusPlus = true;
break;
case lldb::eLanguageTypeObjC:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
+ m_compiler->getLangOpts().ObjC = true;
// FIXME: the following language option is a temporary workaround,
// to "ask for ObjC, get ObjC++" (see comment above).
m_compiler->getLangOpts().CPlusPlus = true;
@@ -399,16 +398,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
LLVM_FALLTHROUGH;
case lldb::eLanguageTypeC_plus_plus_03:
m_compiler->getLangOpts().CPlusPlus = true;
- // FIXME: the following language option is a temporary workaround,
- // to "ask for C++, get ObjC++". Apple hopes to remove this requirement on
- // non-Apple platforms, but for now it is needed.
- m_compiler->getLangOpts().ObjC1 = true;
+ if (process_sp)
+ m_compiler->getLangOpts().ObjC =
+ process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC) != nullptr;
break;
case lldb::eLanguageTypeObjC_plus_plus:
case lldb::eLanguageTypeUnknown:
default:
- m_compiler->getLangOpts().ObjC1 = true;
- m_compiler->getLangOpts().ObjC2 = true;
+ m_compiler->getLangOpts().ObjC = true;
m_compiler->getLangOpts().CPlusPlus = true;
m_compiler->getLangOpts().CPlusPlus11 = true;
m_compiler->getHeaderSearchOpts().UseLibcxx = true;
@@ -432,7 +429,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
// long time parsing and importing debug information.
m_compiler->getLangOpts().SpellChecking = false;
- if (process_sp && m_compiler->getLangOpts().ObjC1) {
+ if (process_sp && m_compiler->getLangOpts().ObjC) {
if (process_sp->GetObjCLanguageRuntime()) {
if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() ==
ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2)
@@ -452,6 +449,10 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
false; // Debuggers get universal access
m_compiler->getLangOpts().DollarIdents =
true; // $ indicates a persistent variable name
+ // We enable all builtin functions beside the builtins from libc/libm (e.g.
+ // 'fopen'). Those libc functions are already correctly handled by LLDB, and
+ // additionally enabling them as expandable builtins is breaking Clang.
+ m_compiler->getLangOpts().NoBuiltin = true;
// Set CodeGen options
m_compiler->getCodeGenOpts().EmitDeclMetadata = true;
@@ -507,15 +508,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
// 8. Most of this we get from the CompilerInstance, but we also want to give
// the context an ExternalASTSource.
- m_selector_table.reset(new SelectorTable());
- m_builtin_context.reset(new Builtin::Context());
- std::unique_ptr<clang::ASTContext> ast_context(
- new ASTContext(m_compiler->getLangOpts(), m_compiler->getSourceManager(),
- m_compiler->getPreprocessor().getIdentifierTable(),
- *m_selector_table.get(), *m_builtin_context.get()));
+ auto &PP = m_compiler->getPreprocessor();
+ auto &builtin_context = PP.getBuiltinInfo();
+ builtin_context.initializeBuiltins(PP.getIdentifierTable(),
+ m_compiler->getLangOpts());
- ast_context->InitBuiltinTypes(m_compiler->getTarget());
+ m_compiler->createASTContext();
+ clang::ASTContext &ast_context = m_compiler->getASTContext();
ClangExpressionHelper *type_system_helper =
dyn_cast<ClangExpressionHelper>(m_expr.GetTypeSystemHelper());
@@ -524,14 +524,13 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
if (decl_map) {
llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source(
decl_map->CreateProxy());
- decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager());
- ast_context->setExternalSource(ast_source);
+ decl_map->InstallASTContext(ast_context, m_compiler->getFileManager());
+ ast_context.setExternalSource(ast_source);
}
m_ast_context.reset(
new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str()));
- m_ast_context->setASTContext(ast_context.get());
- m_compiler->setASTContext(ast_context.release());
+ m_ast_context->setASTContext(&ast_context);
std::string module_name("$__lldb_module");
@@ -544,7 +543,270 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope,
ClangExpressionParser::~ClangExpressionParser() {}
+namespace {
+
+//----------------------------------------------------------------------
+/// @class CodeComplete
+///
+/// A code completion consumer for the clang Sema that is responsible for
+/// creating the completion suggestions when a user requests completion
+/// of an incomplete `expr` invocation.
+//----------------------------------------------------------------------
+class CodeComplete : public CodeCompleteConsumer {
+ CodeCompletionTUInfo m_info;
+
+ std::string m_expr;
+ unsigned m_position = 0;
+ CompletionRequest &m_request;
+ /// The printing policy we use when printing declarations for our completion
+ /// descriptions.
+ clang::PrintingPolicy m_desc_policy;
+
+ /// Returns true if the given character can be used in an identifier.
+ /// This also returns true for numbers because for completion we usually
+ /// just iterate backwards over iterators.
+ ///
+ /// Note: lldb uses '$' in its internal identifiers, so we also allow this.
+ static bool IsIdChar(char c) {
+ return c == '_' || std::isalnum(c) || c == '$';
+ }
+
+ /// Returns true if the given character is used to separate arguments
+ /// in the command line of lldb.
+ static bool IsTokenSeparator(char c) { return c == ' ' || c == '\t'; }
+
+ /// Drops all tokens in front of the expression that are unrelated for
+ /// the completion of the cmd line. 'unrelated' means here that the token
+ /// is not interested for the lldb completion API result.
+ StringRef dropUnrelatedFrontTokens(StringRef cmd) {
+ if (cmd.empty())
+ return cmd;
+
+ // If we are at the start of a word, then all tokens are unrelated to
+ // the current completion logic.
+ if (IsTokenSeparator(cmd.back()))
+ return StringRef();
+
+ // Remove all previous tokens from the string as they are unrelated
+ // to completing the current token.
+ StringRef to_remove = cmd;
+ while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) {
+ to_remove = to_remove.drop_back();
+ }
+ cmd = cmd.drop_front(to_remove.size());
+
+ return cmd;
+ }
+
+ /// Removes the last identifier token from the given cmd line.
+ StringRef removeLastToken(StringRef cmd) {
+ while (!cmd.empty() && IsIdChar(cmd.back())) {
+ cmd = cmd.drop_back();
+ }
+ return cmd;
+ }
+
+ /// Attemps to merge the given completion from the given position into the
+ /// existing command. Returns the completion string that can be returned to
+ /// the lldb completion API.
+ std::string mergeCompletion(StringRef existing, unsigned pos,
+ StringRef completion) {
+ StringRef existing_command = existing.substr(0, pos);
+ // We rewrite the last token with the completion, so let's drop that
+ // token from the command.
+ existing_command = removeLastToken(existing_command);
+ // We also should remove all previous tokens from the command as they
+ // would otherwise be added to the completion that already has the
+ // completion.
+ existing_command = dropUnrelatedFrontTokens(existing_command);
+ return existing_command.str() + completion.str();
+ }
+
+public:
+ /// Constructs a CodeComplete consumer that can be attached to a Sema.
+ /// @param[out] matches
+ /// The list of matches that the lldb completion API expects as a result.
+ /// This may already contain matches, so it's only allowed to append
+ /// to this variable.
+ /// @param[out] expr
+ /// The whole expression string that we are currently parsing. This
+ /// string needs to be equal to the input the user typed, and NOT the
+ /// final code that Clang is parsing.
+ /// @param[out] position
+ /// The character position of the user cursor in the `expr` parameter.
+ ///
+ CodeComplete(CompletionRequest &request, clang::LangOptions ops,
+ std::string expr, unsigned position)
+ : CodeCompleteConsumer(CodeCompleteOptions(), false),
+ m_info(std::make_shared<GlobalCodeCompletionAllocator>()), m_expr(expr),
+ m_position(position), m_request(request), m_desc_policy(ops) {
+
+ // Ensure that the printing policy is producing a description that is as
+ // short as possible.
+ m_desc_policy.SuppressScope = true;
+ m_desc_policy.SuppressTagKeyword = true;
+ m_desc_policy.FullyQualifiedName = false;
+ m_desc_policy.TerseOutput = true;
+ m_desc_policy.IncludeNewlines = false;
+ m_desc_policy.UseVoidForZeroParams = false;
+ m_desc_policy.Bool = true;
+ }
+
+ /// Deregisters and destroys this code-completion consumer.
+ virtual ~CodeComplete() {}
+
+ /// \name Code-completion filtering
+ /// Check if the result should be filtered out.
+ bool isResultFilteredOut(StringRef Filter,
+ CodeCompletionResult Result) override {
+ // This code is mostly copied from CodeCompleteConsumer.
+ switch (Result.Kind) {
+ case CodeCompletionResult::RK_Declaration:
+ return !(
+ Result.Declaration->getIdentifier() &&
+ Result.Declaration->getIdentifier()->getName().startswith(Filter));
+ case CodeCompletionResult::RK_Keyword:
+ return !StringRef(Result.Keyword).startswith(Filter);
+ case CodeCompletionResult::RK_Macro:
+ return !Result.Macro->getName().startswith(Filter);
+ case CodeCompletionResult::RK_Pattern:
+ return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
+ }
+ // If we trigger this assert or the above switch yields a warning, then
+ // CodeCompletionResult has been enhanced with more kinds of completion
+ // results. Expand the switch above in this case.
+ assert(false && "Unknown completion result type?");
+ // If we reach this, then we should just ignore whatever kind of unknown
+ // result we got back. We probably can't turn it into any kind of useful
+ // completion suggestion with the existing code.
+ return true;
+ }
+
+ /// \name Code-completion callbacks
+ /// Process the finalized code-completion results.
+ void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context,
+ CodeCompletionResult *Results,
+ unsigned NumResults) override {
+
+ // The Sema put the incomplete token we try to complete in here during
+ // lexing, so we need to retrieve it here to know what we are completing.
+ StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
+
+ // Iterate over all the results. Filter out results we don't want and
+ // process the rest.
+ for (unsigned I = 0; I != NumResults; ++I) {
+ // Filter the results with the information from the Sema.
+ if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
+ continue;
+
+ CodeCompletionResult &R = Results[I];
+ std::string ToInsert;
+ std::string Description;
+ // Handle the different completion kinds that come from the Sema.
+ switch (R.Kind) {
+ case CodeCompletionResult::RK_Declaration: {
+ const NamedDecl *D = R.Declaration;
+ ToInsert = R.Declaration->getNameAsString();
+ // If we have a function decl that has no arguments we want to
+ // complete the empty parantheses for the user. If the function has
+ // arguments, we at least complete the opening bracket.
+ if (const FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
+ if (F->getNumParams() == 0)
+ ToInsert += "()";
+ else
+ ToInsert += "(";
+ raw_string_ostream OS(Description);
+ F->print(OS, m_desc_policy, false);
+ OS.flush();
+ } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
+ Description = V->getType().getAsString(m_desc_policy);
+ } else if (const FieldDecl *F = dyn_cast<FieldDecl>(D)) {
+ Description = F->getType().getAsString(m_desc_policy);
+ } else if (const NamespaceDecl *N = dyn_cast<NamespaceDecl>(D)) {
+ // If we try to complete a namespace, then we can directly append
+ // the '::'.
+ if (!N->isAnonymousNamespace())
+ ToInsert += "::";
+ }
+ break;
+ }
+ case CodeCompletionResult::RK_Keyword:
+ ToInsert = R.Keyword;
+ break;
+ case CodeCompletionResult::RK_Macro:
+ ToInsert = R.Macro->getName().str();
+ break;
+ case CodeCompletionResult::RK_Pattern:
+ ToInsert = R.Pattern->getTypedText();
+ break;
+ }
+ // At this point all information is in the ToInsert string.
+
+ // We also filter some internal lldb identifiers here. The user
+ // shouldn't see these.
+ if (StringRef(ToInsert).startswith("$__lldb_"))
+ continue;
+ if (!ToInsert.empty()) {
+ // Merge the suggested Token into the existing command line to comply
+ // with the kind of result the lldb API expects.
+ std::string CompletionSuggestion =
+ mergeCompletion(m_expr, m_position, ToInsert);
+ m_request.AddCompletion(CompletionSuggestion, Description);
+ }
+ }
+ }
+
+ /// \param S the semantic-analyzer object for which code-completion is being
+ /// done.
+ ///
+ /// \param CurrentArg the index of the current argument.
+ ///
+ /// \param Candidates an array of overload candidates.
+ ///
+ /// \param NumCandidates the number of overload candidates
+ void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+ OverloadCandidate *Candidates,
+ unsigned NumCandidates,
+ SourceLocation OpenParLoc) override {
+ // At the moment we don't filter out any overloaded candidates.
+ }
+
+ CodeCompletionAllocator &getAllocator() override {
+ return m_info.getAllocator();
+ }
+
+ CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return m_info; }
+};
+} // namespace
+
+bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line,
+ unsigned pos, unsigned typed_pos) {
+ DiagnosticManager mgr;
+ // We need the raw user expression here because that's what the CodeComplete
+ // class uses to provide completion suggestions.
+ // However, the `Text` method only gives us the transformed expression here.
+ // To actually get the raw user input here, we have to cast our expression to
+ // the LLVMUserExpression which exposes the right API. This should never fail
+ // as we always have a ClangUserExpression whenever we call this.
+ LLVMUserExpression &llvm_expr = *static_cast<LLVMUserExpression *>(&m_expr);
+ CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr.GetUserText(),
+ typed_pos);
+ // We don't need a code generator for parsing.
+ m_code_generator.reset();
+ // Start parsing the expression with our custom code completion consumer.
+ ParseInternal(mgr, &CC, line, pos);
+ return true;
+}
+
unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
+ return ParseInternal(diagnostic_manager);
+}
+
+unsigned
+ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager,
+ CodeCompleteConsumer *completion_consumer,
+ unsigned completion_line,
+ unsigned completion_column) {
ClangDiagnosticManagerAdapter *adapter =
static_cast<ClangDiagnosticManagerAdapter *>(
m_compiler->getDiagnostics().getClient());
@@ -557,10 +819,20 @@ unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
clang::SourceManager &source_mgr = m_compiler->getSourceManager();
bool created_main_file = false;
- if (m_compiler->getCodeGenOpts().getDebugInfo() ==
- codegenoptions::FullDebugInfo) {
+
+ // Clang wants to do completion on a real file known by Clang's file manager,
+ // so we have to create one to make this work.
+ // TODO: We probably could also simulate to Clang's file manager that there
+ // is a real file that contains our code.
+ bool should_create_file = completion_consumer != nullptr;
+
+ // We also want a real file on disk if we generate full debug info.
+ should_create_file |= m_compiler->getCodeGenOpts().getDebugInfo() ==
+ codegenoptions::FullDebugInfo;
+
+ if (should_create_file) {
int temp_fd = -1;
- llvm::SmallString<PATH_MAX> result_path;
+ llvm::SmallString<128> result_path;
if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) {
tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr");
std::string temp_source_path = tmpdir_file_spec.GetPath();
@@ -603,14 +875,30 @@ unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) {
if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap())
decl_map->InstallCodeGenerator(m_code_generator.get());
+ // If we want to parse for code completion, we need to attach our code
+ // completion consumer to the Sema and specify a completion position.
+ // While parsing the Sema will call this consumer with the provided
+ // completion suggestions.
+ if (completion_consumer) {
+ auto main_file = source_mgr.getFileEntryForID(source_mgr.getMainFileID());
+ auto &PP = m_compiler->getPreprocessor();
+ // Lines and columns start at 1 in Clang, but code completion positions are
+ // indexed from 0, so we need to add 1 to the line and column here.
+ ++completion_line;
+ ++completion_column;
+ PP.SetCodeCompletionPoint(main_file, completion_line, completion_column);
+ }
+
if (ast_transformer) {
ast_transformer->Initialize(m_compiler->getASTContext());
ParseAST(m_compiler->getPreprocessor(), ast_transformer,
- m_compiler->getASTContext());
+ m_compiler->getASTContext(), false, TU_Complete,
+ completion_consumer);
} else {
m_code_generator->Initialize(m_compiler->getASTContext());
ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(),
- m_compiler->getASTContext());
+ m_compiler->getASTContext(), false, TU_Complete,
+ completion_consumer);
}
diag_buf->EndSourceFile();
@@ -891,9 +1179,9 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution(
if (!dynamic_checkers->Install(install_diagnostics, exe_ctx)) {
if (install_diagnostics.Diagnostics().size())
- err.SetErrorString("couldn't install checkers, unknown error");
- else
err.SetErrorString(install_diagnostics.GetString().c_str());
+ else
+ err.SetErrorString("couldn't install checkers, unknown error");
return err;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 4058ec1270b3..03ff55f614d5 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -20,6 +20,10 @@
#include <string>
#include <vector>
+namespace clang {
+class CodeCompleteConsumer;
+}
+
namespace lldb_private {
class IRExecutionUnit;
@@ -58,6 +62,9 @@ public:
//------------------------------------------------------------------
~ClangExpressionParser() override;
+ bool Complete(CompletionRequest &request, unsigned line, unsigned pos,
+ unsigned typed_pos) override;
+
//------------------------------------------------------------------
/// Parse a single expression and convert it to IR using Clang. Don't wrap
/// the expression in anything at all.
@@ -143,16 +150,39 @@ public:
std::string GetClangTargetABI(const ArchSpec &target_arch);
private:
+ //------------------------------------------------------------------
+ /// Parses the expression.
+ ///
+ /// @param[in] diagnostic_manager
+ /// The diagnostic manager that should receive the diagnostics
+ /// from the parsing process.
+ ///
+ /// @param[in] completion
+ /// The completion consumer that should be used during parsing
+ /// (or a nullptr if no consumer should be attached).
+ ///
+ /// @param[in] completion_line
+ /// The line in which the completion marker should be placed.
+ /// The first line is represented by the value 0.
+ ///
+ /// @param[in] completion_column
+ /// The column in which the completion marker should be placed.
+ /// The first column is represented by the value 0.
+ ///
+ /// @return
+ /// The number of parsing errors.
+ //-------------------------------------------------------------------
+ unsigned ParseInternal(DiagnosticManager &diagnostic_manager,
+ clang::CodeCompleteConsumer *completion = nullptr,
+ unsigned completion_line = 0,
+ unsigned completion_column = 0);
+
std::unique_ptr<llvm::LLVMContext>
m_llvm_context; ///< The LLVM context to generate IR into
std::unique_ptr<clang::FileManager>
m_file_manager; ///< The Clang file manager object used by the compiler
std::unique_ptr<clang::CompilerInstance>
m_compiler; ///< The Clang compiler used to parse expressions into IR
- std::unique_ptr<clang::Builtin::Context>
- m_builtin_context; ///< Context for Clang built-ins
- std::unique_ptr<clang::SelectorTable>
- m_selector_table; ///< Selector table for Objective-C methods
std::unique_ptr<clang::CodeGenerator>
m_code_generator; ///< The Clang object that generates IR
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
index 7d5ced5b4705..6886f0940adb 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h
@@ -10,20 +10,16 @@
#ifndef liblldb_ClangExpressionVariable_h_
#define liblldb_ClangExpressionVariable_h_
-// C Includes
#include <signal.h>
#include <stdint.h>
#include <string.h>
-// C++ Includes
#include <map>
#include <string>
#include <vector>
-// Other libraries and framework includes
#include "llvm/Support/Casting.h"
-// Project includes
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ExpressionVariable.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
index e3e0ed49181e..8ec9ff2235f5 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp
@@ -12,9 +12,6 @@
#include "ASTStructExtractor.h"
#include "ClangExpressionParser.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
#include "clang/CodeGen/CodeGenAction.h"
@@ -25,9 +22,7 @@
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
-// Project includes
#include "lldb/Core/Module.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Expression/IRExecutionUnit.h"
@@ -44,6 +39,7 @@
#include "lldb/Target/ThreadPlanCallFunction.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
using namespace lldb_private;
diff --git a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
index 438cf0c713da..9d933bfa6095 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ClangFunctionCaller_h_
#define liblldb_ClangFunctionCaller_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "ClangExpressionHelper.h"
#include "lldb/Core/Address.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
index 4251d2ee75b9..44a13353818a 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangHost.cpp
@@ -17,7 +17,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
-// Project includes
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#if !defined(_WIN32)
#include "lldb/Host/posix/HostInfoPosix.h"
@@ -42,7 +42,7 @@ static bool DefaultComputeClangDirectory(FileSpec &file_spec) {
#if defined(__APPLE__)
static bool VerifyClangPath(const llvm::Twine &clang_path) {
- if (llvm::sys::fs::is_directory(clang_path))
+ if (FileSystem::Instance().IsDirectory(clang_path))
return true;
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log)
@@ -84,7 +84,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec,
"Developer/Toolchains/XcodeDefault.xctoolchain",
swift_clang_resource_dir);
if (!verify || VerifyClangPath(clang_path)) {
- file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native);
+ file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file_spec);
return true;
}
} else if (parent != r_end && *parent == "PrivateFrameworks" &&
@@ -98,7 +99,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec,
raw_path.resize(parent - r_end);
llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir);
if (!verify || VerifyClangPath(clang_path)) {
- file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native);
+ file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file_spec);
return true;
}
raw_path = lldb_shlib_spec.GetPath();
@@ -110,7 +112,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec,
// Fall back to the Clang resource directory inside the framework.
raw_path.append("LLDB.framework/Resources/Clang");
- file_spec.SetFile(raw_path.c_str(), true, FileSpec::Style::native);
+ file_spec.SetFile(raw_path.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(file_spec);
return true;
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 665195f01774..ced21dfe0dda 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -7,11 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
@@ -24,7 +21,6 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Threading.h"
-// Project includes
#include "ClangHost.h"
#include "ClangModulesDeclVendor.h"
@@ -601,7 +597,7 @@ ClangModulesDeclVendor::Create(Target &target) {
{
FileSpec clang_resource_dir = GetClangResourceDir();
- if (llvm::sys::fs::is_directory(clang_resource_dir.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) {
compiler_invocation_arguments.push_back("-resource-dir");
compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());
}
@@ -612,7 +608,8 @@ ClangModulesDeclVendor::Create(Target &target) {
new StoringDiagnosticConsumer);
std::vector<const char *> compiler_invocation_argument_cstrs;
-
+ compiler_invocation_argument_cstrs.reserve(
+ compiler_invocation_arguments.size());
for (const std::string &arg : compiler_invocation_arguments) {
compiler_invocation_argument_cstrs.push_back(arg.c_str());
}
diff --git a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index 59126974616d..c4438c7e2203 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -10,12 +10,8 @@
#ifndef liblldb_ClangPersistentVariables_h_
#define liblldb_ClangPersistentVariables_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
-// Project includes
#include "ClangExpressionVariable.h"
#include "ClangModulesDeclVendor.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 2e61f704127a..f42955df07aa 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -376,9 +376,9 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) {
}
}
-llvm::Optional<lldb::LanguageType> ClangUserExpression::GetLanguageForExpr(
+void ClangUserExpression::UpdateLanguageForExpr(
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
- lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown;
+ m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown;
std::string prefix = m_expr_prefix;
@@ -390,20 +390,29 @@ llvm::Optional<lldb::LanguageType> ClangUserExpression::GetLanguageForExpr(
m_expr_text.c_str()));
if (m_in_cplusplus_method)
- lang_type = lldb::eLanguageTypeC_plus_plus;
+ m_expr_lang = lldb::eLanguageTypeC_plus_plus;
else if (m_in_objectivec_method)
- lang_type = lldb::eLanguageTypeObjC;
+ m_expr_lang = lldb::eLanguageTypeObjC;
else
- lang_type = lldb::eLanguageTypeC;
+ m_expr_lang = lldb::eLanguageTypeC;
- if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method,
- exe_ctx)) {
+ if (!source_code->GetText(m_transformed_text, m_expr_lang,
+ m_in_static_method, exe_ctx)) {
diagnostic_manager.PutString(eDiagnosticSeverityError,
"couldn't construct expression body");
- return llvm::Optional<lldb::LanguageType>();
+ return;
+ }
+
+ // Find and store the start position of the original code inside the
+ // transformed code. We need this later for the code completion.
+ std::size_t original_start;
+ std::size_t original_end;
+ bool found_bounds = source_code->GetOriginalBodyBounds(
+ m_transformed_text, m_expr_lang, original_start, original_end);
+ if (found_bounds) {
+ m_user_expression_start_pos = original_start;
}
}
- return lang_type;
}
bool ClangUserExpression::PrepareForParsing(
@@ -427,6 +436,8 @@ bool ClangUserExpression::PrepareForParsing(
ApplyObjcCastHack(m_expr_text);
SetupDeclVendor(exe_ctx, m_target);
+
+ UpdateLanguageForExpr(diagnostic_manager, exe_ctx);
return true;
}
@@ -440,11 +451,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
if (!PrepareForParsing(diagnostic_manager, exe_ctx))
return false;
- lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown;
- if (auto new_lang = GetLanguageForExpr(diagnostic_manager, exe_ctx)) {
- lang_type = new_lang.getValue();
- }
-
if (log)
log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
@@ -504,7 +510,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
const std::string &fixed_expression =
diagnostic_manager.GetFixedExpression();
if (ExpressionSourceCode::GetOriginalBodyBounds(
- fixed_expression, lang_type, fixed_start, fixed_end))
+ fixed_expression, m_expr_lang, fixed_start, fixed_end))
m_fixed_text =
fixed_expression.substr(fixed_start, fixed_end - fixed_start);
}
@@ -591,6 +597,116 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager,
return true;
}
+//------------------------------------------------------------------
+/// Converts an absolute position inside a given code string into
+/// a column/line pair.
+///
+/// @param[in] abs_pos
+/// A absolute position in the code string that we want to convert
+/// to a column/line pair.
+///
+/// @param[in] code
+/// A multi-line string usually representing source code.
+///
+/// @param[out] line
+/// The line in the code that contains the given absolute position.
+/// The first line in the string is indexed as 1.
+///
+/// @param[out] column
+/// The column in the line that contains the absolute position.
+/// The first character in a line is indexed as 0.
+//------------------------------------------------------------------
+static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code,
+ unsigned &line, unsigned &column) {
+ // Reset to code position to beginning of the file.
+ line = 0;
+ column = 0;
+
+ assert(abs_pos <= code.size() && "Absolute position outside code string?");
+
+ // We have to walk up to the position and count lines/columns.
+ for (std::size_t i = 0; i < abs_pos; ++i) {
+ // If we hit a line break, we go back to column 0 and enter a new line.
+ // We only handle \n because that's what we internally use to make new
+ // lines for our temporary code strings.
+ if (code[i] == '\n') {
+ ++line;
+ column = 0;
+ continue;
+ }
+ ++column;
+ }
+}
+
+bool ClangUserExpression::Complete(ExecutionContext &exe_ctx,
+ CompletionRequest &request,
+ unsigned complete_pos) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+
+ // We don't want any visible feedback when completing an expression. Mostly
+ // because the results we get from an incomplete invocation are probably not
+ // correct.
+ DiagnosticManager diagnostic_manager;
+
+ if (!PrepareForParsing(diagnostic_manager, exe_ctx))
+ return false;
+
+ if (log)
+ log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str());
+
+ //////////////////////////
+ // Parse the expression
+ //
+
+ m_materializer_ap.reset(new Materializer());
+
+ ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true);
+
+ OnExit on_exit([this]() { ResetDeclMap(); });
+
+ if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) {
+ diagnostic_manager.PutString(
+ eDiagnosticSeverityError,
+ "current process state is unsuitable for expression parsing");
+
+ return false;
+ }
+
+ if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) {
+ DeclMap()->SetLookupsEnabled(true);
+ }
+
+ Process *process = exe_ctx.GetProcessPtr();
+ ExecutionContextScope *exe_scope = process;
+
+ if (!exe_scope)
+ exe_scope = exe_ctx.GetTargetPtr();
+
+ ClangExpressionParser parser(exe_scope, *this, false);
+
+ // We have to find the source code location where the user text is inside
+ // the transformed expression code. When creating the transformed text, we
+ // already stored the absolute position in the m_transformed_text string. The
+ // only thing left to do is to transform it into the line:column format that
+ // Clang expects.
+
+ // The line and column of the user expression inside the transformed source
+ // code.
+ unsigned user_expr_line, user_expr_column;
+ if (m_user_expression_start_pos.hasValue())
+ AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text,
+ user_expr_line, user_expr_column);
+ else
+ return false;
+
+ // The actual column where we have to complete is the start column of the
+ // user expression + the offset inside the user code that we were given.
+ const unsigned completion_column = user_expr_column + complete_pos;
+ parser.Complete(request, user_expr_line, completion_column, complete_pos);
+
+ return true;
+}
+
bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx,
std::vector<lldb::addr_t> &args,
lldb::addr_t struct_address,
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
index ac363bf91747..7e4cba661850 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h
@@ -10,12 +10,8 @@
#ifndef liblldb_ClangUserExpression_h_
#define liblldb_ClangUserExpression_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "ASTResultSynthesizer.h"
#include "ASTStructExtractor.h"
#include "ClangExpressionDeclMap.h"
@@ -143,6 +139,9 @@ public:
lldb_private::ExecutionPolicy execution_policy,
bool keep_result_in_memory, bool generate_debug_info) override;
+ bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request,
+ unsigned complete_pos) override;
+
ExpressionTypeSystemHelper *GetTypeSystemHelper() override {
return &m_type_system_helper;
}
@@ -174,8 +173,8 @@ private:
lldb::addr_t struct_address,
DiagnosticManager &diagnostic_manager) override;
- llvm::Optional<lldb::LanguageType> GetLanguageForExpr(
- DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx);
+ void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager,
+ ExecutionContext &exe_ctx);
bool SetupPersistentState(DiagnosticManager &diagnostic_manager,
ExecutionContext &exe_ctx);
bool PrepareForParsing(DiagnosticManager &diagnostic_manager,
@@ -198,6 +197,13 @@ private:
lldb::TargetSP m_target_sp;
};
+ /// The language type of the current expression.
+ lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown;
+
+ /// The absolute character position in the transformed source code where the
+ /// user code (as typed by the user) starts. If the variable is empty, then we
+ /// were not able to calculate this position.
+ llvm::Optional<size_t> m_user_expression_start_pos;
ResultDelegate m_result_delegate;
};
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
index 0f2aeef27e57..fe6ca450a79d 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp
@@ -11,13 +11,11 @@
#include "ClangExpressionDeclMap.h"
#include "ClangExpressionParser.h"
-// C Includes
#include <stdio.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
-// C++ Includes
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
diff --git a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
index a897a2b17087..b0650f0eda02 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
+++ b/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h
@@ -10,14 +10,10 @@
#ifndef liblldb_ClangUtilityFunction_h_
#define liblldb_ClangUtilityFunction_h_
-// C Includes
-// C++ Includes
#include <map>
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "ClangExpressionHelper.h"
#include "lldb/Core/ClangForward.h"
diff --git a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index e51c9ee07b9f..3a7cd58b70ab 100644
--- a/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -25,7 +25,6 @@
#include "clang/AST/ASTContext.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/dwarf.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
@@ -36,6 +35,7 @@
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
#include <map>
@@ -310,12 +310,14 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
lldb::TargetSP target_sp(m_execution_unit.GetTarget());
lldb_private::ExecutionContext exe_ctx(target_sp, true);
- if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
+ llvm::Optional<uint64_t> bit_size =
+ m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
+ if (!bit_size) {
lldb_private::StreamString type_desc_stream;
m_result_type.DumpTypeDescription(&type_desc_stream);
if (log)
- log->Printf("Result type has size 0");
+ log->Printf("Result type has unknown size");
m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
"couldn't be determined\n",
@@ -334,7 +336,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
if (log)
log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
- m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
+ m_result_name.GetCString(),
+ m_result_type.GetByteSize(nullptr).getValueOr(0));
// Construct a new result global and set up its metadata
@@ -778,11 +781,8 @@ bool IRForTarget::RewriteObjCConstStrings() {
static bool IsObjCSelectorRef(Value *value) {
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- if (!global_variable || !global_variable->hasName() ||
- !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
- return false;
-
- return true;
+ return !(!global_variable || !global_variable->hasName() ||
+ !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
}
// This function does not report errors; its callers are responsible.
@@ -953,11 +953,8 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
static bool IsObjCClassReference(Value *value) {
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
- if (!global_variable || !global_variable->hasName() ||
- !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"))
- return false;
-
- return true;
+ return !(!global_variable || !global_variable->hasName() ||
+ !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
}
// This function does not report errors; its callers are responsible.
@@ -1259,12 +1256,9 @@ bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
llvm::NextPowerOf2(constant_size) * 8);
lldb_private::Status get_data_error;
- if (!scalar.GetAsMemoryData(data, constant_size,
- lldb_private::endian::InlHostByteOrder(),
- get_data_error))
- return false;
-
- return true;
+ return scalar.GetAsMemoryData(data, constant_size,
+ lldb_private::endian::InlHostByteOrder(),
+ get_data_error) != 0;
} else if (ConstantDataArray *array_initializer =
dyn_cast<ConstantDataArray>(initializer)) {
if (array_initializer->isString()) {
@@ -1376,7 +1370,9 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
value_type = global_variable->getType();
}
- const uint64_t value_size = compiler_type.GetByteSize(nullptr);
+ llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
+ if (!value_size)
+ return false;
lldb::offset_t value_alignment =
(compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
@@ -1387,13 +1383,13 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
lldb_private::ClangUtil::GetQualType(compiler_type)
.getAsString()
.c_str(),
- PrintType(value_type).c_str(), value_size, value_alignment);
+ PrintType(value_type).c_str(), *value_size, value_alignment);
}
if (named_decl &&
!m_decl_map->AddValueToStruct(
named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
- value_size, value_alignment)) {
+ *value_size, value_alignment)) {
if (!global_variable->hasExternalLinkage())
return true;
else
diff --git a/source/Plugins/ExpressionParser/Go/CMakeLists.txt b/source/Plugins/ExpressionParser/Go/CMakeLists.txt
deleted file mode 100644
index 3d552aafa0d7..000000000000
--- a/source/Plugins/ExpressionParser/Go/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginExpressionParserGo PLUGIN
- GoLexer.cpp
- GoParser.cpp
- GoUserExpression.cpp
-
- LINK_LIBS
- lldbCore
- lldbExpression
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/ExpressionParser/Go/GoAST.h b/source/Plugins/ExpressionParser/Go/GoAST.h
deleted file mode 100644
index d24e6c548718..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoAST.h
+++ /dev/null
@@ -1,1977 +0,0 @@
-//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// DO NOT EDIT.
-// Generated by gen_go_ast.py
-
-#ifndef liblldb_GoAST_h
-#define liblldb_GoAST_h
-
-#include "Plugins/ExpressionParser/Go/GoLexer.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "llvm/Support/Casting.h"
-
-namespace lldb_private {
-
-class GoASTNode {
-public:
- typedef GoLexer::TokenType TokenType;
- typedef GoLexer::Token Token;
- enum ChanDir {
- eChanBidir,
- eChanSend,
- eChanRecv,
- };
- enum NodeKind {
- eBadDecl,
- eFuncDecl,
- eGenDecl,
- eArrayType,
- eBadExpr,
- eBasicLit,
- eBinaryExpr,
- eIdent,
- eCallExpr,
- eChanType,
- eCompositeLit,
- eEllipsis,
- eFuncType,
- eFuncLit,
- eIndexExpr,
- eInterfaceType,
- eKeyValueExpr,
- eMapType,
- eParenExpr,
- eSelectorExpr,
- eSliceExpr,
- eStarExpr,
- eStructType,
- eTypeAssertExpr,
- eUnaryExpr,
- eImportSpec,
- eTypeSpec,
- eValueSpec,
- eAssignStmt,
- eBadStmt,
- eBlockStmt,
- eBranchStmt,
- eCaseClause,
- eCommClause,
- eDeclStmt,
- eDeferStmt,
- eEmptyStmt,
- eExprStmt,
- eForStmt,
- eGoStmt,
- eIfStmt,
- eIncDecStmt,
- eLabeledStmt,
- eRangeStmt,
- eReturnStmt,
- eSelectStmt,
- eSendStmt,
- eSwitchStmt,
- eTypeSwitchStmt,
- eField,
- eFieldList,
- };
-
- virtual ~GoASTNode() = default;
-
- NodeKind GetKind() const { return m_kind; }
-
- virtual const char *GetKindName() const = 0;
-
- template <typename V> void WalkChildren(V &v);
-
-protected:
- explicit GoASTNode(NodeKind kind) : m_kind(kind) {}
-
-private:
- const NodeKind m_kind;
-
- GoASTNode(const GoASTNode &) = delete;
- const GoASTNode &operator=(const GoASTNode &) = delete;
-};
-
-class GoASTDecl : public GoASTNode {
-public:
- template <typename R, typename V> R Visit(V *v) const;
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl;
- }
-
-protected:
- explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) {}
-
-private:
- GoASTDecl(const GoASTDecl &) = delete;
- const GoASTDecl &operator=(const GoASTDecl &) = delete;
-};
-
-class GoASTExpr : public GoASTNode {
-public:
- template <typename R, typename V> R Visit(V *v) const;
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr;
- }
-
-protected:
- explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) {}
-
-private:
- GoASTExpr(const GoASTExpr &) = delete;
- const GoASTExpr &operator=(const GoASTExpr &) = delete;
-};
-
-class GoASTSpec : public GoASTNode {
-public:
- template <typename R, typename V> R Visit(V *v) const;
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec;
- }
-
-protected:
- explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) {}
-
-private:
- GoASTSpec(const GoASTSpec &) = delete;
- const GoASTSpec &operator=(const GoASTSpec &) = delete;
-};
-
-class GoASTStmt : public GoASTNode {
-public:
- template <typename R, typename V> R Visit(V *v) const;
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt;
- }
-
-protected:
- explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) {}
-
-private:
- GoASTStmt(const GoASTStmt &) = delete;
- const GoASTStmt &operator=(const GoASTStmt &) = delete;
-};
-
-class GoASTArrayType : public GoASTExpr {
-public:
- GoASTArrayType(GoASTExpr *len, GoASTExpr *elt)
- : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {}
- ~GoASTArrayType() override = default;
-
- const char *GetKindName() const override { return "ArrayType"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eArrayType; }
-
- const GoASTExpr *GetLen() const { return m_len_up.get(); }
- void SetLen(GoASTExpr *len) { m_len_up.reset(len); }
-
- const GoASTExpr *GetElt() const { return m_elt_up.get(); }
- void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_len_up;
- std::unique_ptr<GoASTExpr> m_elt_up;
-
- GoASTArrayType(const GoASTArrayType &) = delete;
- const GoASTArrayType &operator=(const GoASTArrayType &) = delete;
-};
-
-class GoASTAssignStmt : public GoASTStmt {
-public:
- explicit GoASTAssignStmt(bool define)
- : GoASTStmt(eAssignStmt), m_define(define) {}
- ~GoASTAssignStmt() override = default;
-
- const char *GetKindName() const override { return "AssignStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eAssignStmt;
- }
-
- size_t NumLhs() const { return m_lhs.size(); }
- const GoASTExpr *GetLhs(int i) const { return m_lhs[i].get(); }
- void AddLhs(GoASTExpr *lhs) {
- m_lhs.push_back(std::unique_ptr<GoASTExpr>(lhs));
- }
-
- size_t NumRhs() const { return m_rhs.size(); }
- const GoASTExpr *GetRhs(int i) const { return m_rhs[i].get(); }
- void AddRhs(GoASTExpr *rhs) {
- m_rhs.push_back(std::unique_ptr<GoASTExpr>(rhs));
- }
-
- bool GetDefine() const { return m_define; }
- void SetDefine(bool define) { m_define = define; }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr>> m_lhs;
- std::vector<std::unique_ptr<GoASTExpr>> m_rhs;
- bool m_define;
-
- GoASTAssignStmt(const GoASTAssignStmt &) = delete;
- const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete;
-};
-
-class GoASTBadDecl : public GoASTDecl {
-public:
- GoASTBadDecl() : GoASTDecl(eBadDecl) {}
- ~GoASTBadDecl() override = default;
-
- const char *GetKindName() const override { return "BadDecl"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eBadDecl; }
-
- GoASTBadDecl(const GoASTBadDecl &) = delete;
- const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete;
-};
-
-class GoASTBadExpr : public GoASTExpr {
-public:
- GoASTBadExpr() : GoASTExpr(eBadExpr) {}
- ~GoASTBadExpr() override = default;
-
- const char *GetKindName() const override { return "BadExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eBadExpr; }
-
- GoASTBadExpr(const GoASTBadExpr &) = delete;
- const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete;
-};
-
-class GoASTBadStmt : public GoASTStmt {
-public:
- GoASTBadStmt() : GoASTStmt(eBadStmt) {}
- ~GoASTBadStmt() override = default;
-
- const char *GetKindName() const override { return "BadStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eBadStmt; }
-
- GoASTBadStmt(const GoASTBadStmt &) = delete;
- const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete;
-};
-
-class GoASTBasicLit : public GoASTExpr {
-public:
- explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {}
- ~GoASTBasicLit() override = default;
-
- const char *GetKindName() const override { return "BasicLit"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eBasicLit; }
-
- Token GetValue() const { return m_value; }
- void SetValue(Token value) { m_value = value; }
-
-private:
- friend class GoASTNode;
- Token m_value;
-
- GoASTBasicLit(const GoASTBasicLit &) = delete;
- const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete;
-};
-
-class GoASTBinaryExpr : public GoASTExpr {
-public:
- GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op)
- : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {}
- ~GoASTBinaryExpr() override = default;
-
- const char *GetKindName() const override { return "BinaryExpr"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eBinaryExpr;
- }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTExpr *GetY() const { return m_y_up.get(); }
- void SetY(GoASTExpr *y) { m_y_up.reset(y); }
-
- TokenType GetOp() const { return m_op; }
- void SetOp(TokenType op) { m_op = op; }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_y_up;
- TokenType m_op;
-
- GoASTBinaryExpr(const GoASTBinaryExpr &) = delete;
- const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete;
-};
-
-class GoASTBlockStmt : public GoASTStmt {
-public:
- GoASTBlockStmt() : GoASTStmt(eBlockStmt) {}
- ~GoASTBlockStmt() override = default;
-
- const char *GetKindName() const override { return "BlockStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eBlockStmt; }
-
- size_t NumList() const { return m_list.size(); }
- const GoASTStmt *GetList(int i) const { return m_list[i].get(); }
- void AddList(GoASTStmt *list) {
- m_list.push_back(std::unique_ptr<GoASTStmt>(list));
- }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTStmt>> m_list;
-
- GoASTBlockStmt(const GoASTBlockStmt &) = delete;
- const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete;
-};
-
-class GoASTIdent : public GoASTExpr {
-public:
- explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {}
- ~GoASTIdent() override = default;
-
- const char *GetKindName() const override { return "Ident"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eIdent; }
-
- Token GetName() const { return m_name; }
- void SetName(Token name) { m_name = name; }
-
-private:
- friend class GoASTNode;
- Token m_name;
-
- GoASTIdent(const GoASTIdent &) = delete;
- const GoASTIdent &operator=(const GoASTIdent &) = delete;
-};
-
-class GoASTBranchStmt : public GoASTStmt {
-public:
- GoASTBranchStmt(GoASTIdent *label, TokenType tok)
- : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {}
- ~GoASTBranchStmt() override = default;
-
- const char *GetKindName() const override { return "BranchStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eBranchStmt;
- }
-
- const GoASTIdent *GetLabel() const { return m_label_up.get(); }
- void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
-
- TokenType GetTok() const { return m_tok; }
- void SetTok(TokenType tok) { m_tok = tok; }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_label_up;
- TokenType m_tok;
-
- GoASTBranchStmt(const GoASTBranchStmt &) = delete;
- const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete;
-};
-
-class GoASTCallExpr : public GoASTExpr {
-public:
- explicit GoASTCallExpr(bool ellipsis)
- : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {}
- ~GoASTCallExpr() override = default;
-
- const char *GetKindName() const override { return "CallExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eCallExpr; }
-
- const GoASTExpr *GetFun() const { return m_fun_up.get(); }
- void SetFun(GoASTExpr *fun) { m_fun_up.reset(fun); }
-
- size_t NumArgs() const { return m_args.size(); }
- const GoASTExpr *GetArgs(int i) const { return m_args[i].get(); }
- void AddArgs(GoASTExpr *args) {
- m_args.push_back(std::unique_ptr<GoASTExpr>(args));
- }
-
- bool GetEllipsis() const { return m_ellipsis; }
- void SetEllipsis(bool ellipsis) { m_ellipsis = ellipsis; }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_fun_up;
- std::vector<std::unique_ptr<GoASTExpr>> m_args;
- bool m_ellipsis;
-
- GoASTCallExpr(const GoASTCallExpr &) = delete;
- const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete;
-};
-
-class GoASTCaseClause : public GoASTStmt {
-public:
- GoASTCaseClause() : GoASTStmt(eCaseClause) {}
- ~GoASTCaseClause() override = default;
-
- const char *GetKindName() const override { return "CaseClause"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eCaseClause;
- }
-
- size_t NumList() const { return m_list.size(); }
- const GoASTExpr *GetList(int i) const { return m_list[i].get(); }
- void AddList(GoASTExpr *list) {
- m_list.push_back(std::unique_ptr<GoASTExpr>(list));
- }
-
- size_t NumBody() const { return m_body.size(); }
- const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
- void AddBody(GoASTStmt *body) {
- m_body.push_back(std::unique_ptr<GoASTStmt>(body));
- }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr>> m_list;
- std::vector<std::unique_ptr<GoASTStmt>> m_body;
-
- GoASTCaseClause(const GoASTCaseClause &) = delete;
- const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete;
-};
-
-class GoASTChanType : public GoASTExpr {
-public:
- GoASTChanType(ChanDir dir, GoASTExpr *value)
- : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {}
- ~GoASTChanType() override = default;
-
- const char *GetKindName() const override { return "ChanType"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eChanType; }
-
- ChanDir GetDir() const { return m_dir; }
- void SetDir(ChanDir dir) { m_dir = dir; }
-
- const GoASTExpr *GetValue() const { return m_value_up.get(); }
- void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
-
-private:
- friend class GoASTNode;
- ChanDir m_dir;
- std::unique_ptr<GoASTExpr> m_value_up;
-
- GoASTChanType(const GoASTChanType &) = delete;
- const GoASTChanType &operator=(const GoASTChanType &) = delete;
-};
-
-class GoASTCommClause : public GoASTStmt {
-public:
- GoASTCommClause() : GoASTStmt(eCommClause) {}
- ~GoASTCommClause() override = default;
-
- const char *GetKindName() const override { return "CommClause"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eCommClause;
- }
-
- const GoASTStmt *GetComm() const { return m_comm_up.get(); }
- void SetComm(GoASTStmt *comm) { m_comm_up.reset(comm); }
-
- size_t NumBody() const { return m_body.size(); }
- const GoASTStmt *GetBody(int i) const { return m_body[i].get(); }
- void AddBody(GoASTStmt *body) {
- m_body.push_back(std::unique_ptr<GoASTStmt>(body));
- }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_comm_up;
- std::vector<std::unique_ptr<GoASTStmt>> m_body;
-
- GoASTCommClause(const GoASTCommClause &) = delete;
- const GoASTCommClause &operator=(const GoASTCommClause &) = delete;
-};
-
-class GoASTCompositeLit : public GoASTExpr {
-public:
- GoASTCompositeLit() : GoASTExpr(eCompositeLit) {}
- ~GoASTCompositeLit() override = default;
-
- const char *GetKindName() const override { return "CompositeLit"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eCompositeLit;
- }
-
- const GoASTExpr *GetType() const { return m_type_up.get(); }
- void SetType(GoASTExpr *type) { m_type_up.reset(type); }
-
- size_t NumElts() const { return m_elts.size(); }
- const GoASTExpr *GetElts(int i) const { return m_elts[i].get(); }
- void AddElts(GoASTExpr *elts) {
- m_elts.push_back(std::unique_ptr<GoASTExpr>(elts));
- }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::vector<std::unique_ptr<GoASTExpr>> m_elts;
-
- GoASTCompositeLit(const GoASTCompositeLit &) = delete;
- const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete;
-};
-
-class GoASTDeclStmt : public GoASTStmt {
-public:
- explicit GoASTDeclStmt(GoASTDecl *decl)
- : GoASTStmt(eDeclStmt), m_decl_up(decl) {}
- ~GoASTDeclStmt() override = default;
-
- const char *GetKindName() const override { return "DeclStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eDeclStmt; }
-
- const GoASTDecl *GetDecl() const { return m_decl_up.get(); }
- void SetDecl(GoASTDecl *decl) { m_decl_up.reset(decl); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTDecl> m_decl_up;
-
- GoASTDeclStmt(const GoASTDeclStmt &) = delete;
- const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete;
-};
-
-class GoASTDeferStmt : public GoASTStmt {
-public:
- explicit GoASTDeferStmt(GoASTCallExpr *call)
- : GoASTStmt(eDeferStmt), m_call_up(call) {}
- ~GoASTDeferStmt() override = default;
-
- const char *GetKindName() const override { return "DeferStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eDeferStmt; }
-
- const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
- void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
-
- GoASTDeferStmt(const GoASTDeferStmt &) = delete;
- const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete;
-};
-
-class GoASTEllipsis : public GoASTExpr {
-public:
- explicit GoASTEllipsis(GoASTExpr *elt)
- : GoASTExpr(eEllipsis), m_elt_up(elt) {}
- ~GoASTEllipsis() override = default;
-
- const char *GetKindName() const override { return "Ellipsis"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eEllipsis; }
-
- const GoASTExpr *GetElt() const { return m_elt_up.get(); }
- void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_elt_up;
-
- GoASTEllipsis(const GoASTEllipsis &) = delete;
- const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete;
-};
-
-class GoASTEmptyStmt : public GoASTStmt {
-public:
- GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {}
- ~GoASTEmptyStmt() override = default;
-
- const char *GetKindName() const override { return "EmptyStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eEmptyStmt; }
-
- GoASTEmptyStmt(const GoASTEmptyStmt &) = delete;
- const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete;
-};
-
-class GoASTExprStmt : public GoASTStmt {
-public:
- explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {}
- ~GoASTExprStmt() override = default;
-
- const char *GetKindName() const override { return "ExprStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eExprStmt; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
-
- GoASTExprStmt(const GoASTExprStmt &) = delete;
- const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete;
-};
-
-class GoASTField : public GoASTNode {
-public:
- GoASTField() : GoASTNode(eField) {}
- ~GoASTField() override = default;
-
- const char *GetKindName() const override { return "Field"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eField; }
-
- size_t NumNames() const { return m_names.size(); }
- const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
- void AddNames(GoASTIdent *names) {
- m_names.push_back(std::unique_ptr<GoASTIdent>(names));
- }
-
- const GoASTExpr *GetType() const { return m_type_up.get(); }
- void SetType(GoASTExpr *type) { m_type_up.reset(type); }
-
- const GoASTBasicLit *GetTag() const { return m_tag_up.get(); }
- void SetTag(GoASTBasicLit *tag) { m_tag_up.reset(tag); }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTIdent>> m_names;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::unique_ptr<GoASTBasicLit> m_tag_up;
-
- GoASTField(const GoASTField &) = delete;
- const GoASTField &operator=(const GoASTField &) = delete;
-};
-
-class GoASTFieldList : public GoASTNode {
-public:
- GoASTFieldList() : GoASTNode(eFieldList) {}
- ~GoASTFieldList() override = default;
-
- const char *GetKindName() const override { return "FieldList"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eFieldList; }
-
- size_t NumList() const { return m_list.size(); }
- const GoASTField *GetList(int i) const { return m_list[i].get(); }
- void AddList(GoASTField *list) {
- m_list.push_back(std::unique_ptr<GoASTField>(list));
- }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTField>> m_list;
-
- GoASTFieldList(const GoASTFieldList &) = delete;
- const GoASTFieldList &operator=(const GoASTFieldList &) = delete;
-};
-
-class GoASTForStmt : public GoASTStmt {
-public:
- GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post,
- GoASTBlockStmt *body)
- : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post),
- m_body_up(body) {}
- ~GoASTForStmt() override = default;
-
- const char *GetKindName() const override { return "ForStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eForStmt; }
-
- const GoASTStmt *GetInit() const { return m_init_up.get(); }
- void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
-
- const GoASTExpr *GetCond() const { return m_cond_up.get(); }
- void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
-
- const GoASTStmt *GetPost() const { return m_post_up.get(); }
- void SetPost(GoASTStmt *post) { m_post_up.reset(post); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_cond_up;
- std::unique_ptr<GoASTStmt> m_post_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTForStmt(const GoASTForStmt &) = delete;
- const GoASTForStmt &operator=(const GoASTForStmt &) = delete;
-};
-
-class GoASTFuncType : public GoASTExpr {
-public:
- GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results)
- : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {}
- ~GoASTFuncType() override = default;
-
- const char *GetKindName() const override { return "FuncType"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncType; }
-
- const GoASTFieldList *GetParams() const { return m_params_up.get(); }
- void SetParams(GoASTFieldList *params) { m_params_up.reset(params); }
-
- const GoASTFieldList *GetResults() const { return m_results_up.get(); }
- void SetResults(GoASTFieldList *results) { m_results_up.reset(results); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_params_up;
- std::unique_ptr<GoASTFieldList> m_results_up;
-
- GoASTFuncType(const GoASTFuncType &) = delete;
- const GoASTFuncType &operator=(const GoASTFuncType &) = delete;
-};
-
-class GoASTFuncDecl : public GoASTDecl {
-public:
- GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type,
- GoASTBlockStmt *body)
- : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type),
- m_body_up(body) {}
- ~GoASTFuncDecl() override = default;
-
- const char *GetKindName() const override { return "FuncDecl"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncDecl; }
-
- const GoASTFieldList *GetRecv() const { return m_recv_up.get(); }
- void SetRecv(GoASTFieldList *recv) { m_recv_up.reset(recv); }
-
- const GoASTIdent *GetName() const { return m_name_up.get(); }
- void SetName(GoASTIdent *name) { m_name_up.reset(name); }
-
- const GoASTFuncType *GetType() const { return m_type_up.get(); }
- void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_recv_up;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTFuncType> m_type_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTFuncDecl(const GoASTFuncDecl &) = delete;
- const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete;
-};
-
-class GoASTFuncLit : public GoASTExpr {
-public:
- GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body)
- : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {}
- ~GoASTFuncLit() override = default;
-
- const char *GetKindName() const override { return "FuncLit"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncLit; }
-
- const GoASTFuncType *GetType() const { return m_type_up.get(); }
- void SetType(GoASTFuncType *type) { m_type_up.reset(type); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFuncType> m_type_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTFuncLit(const GoASTFuncLit &) = delete;
- const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete;
-};
-
-class GoASTGenDecl : public GoASTDecl {
-public:
- explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {}
- ~GoASTGenDecl() override = default;
-
- const char *GetKindName() const override { return "GenDecl"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eGenDecl; }
-
- TokenType GetTok() const { return m_tok; }
- void SetTok(TokenType tok) { m_tok = tok; }
-
- size_t NumSpecs() const { return m_specs.size(); }
- const GoASTSpec *GetSpecs(int i) const { return m_specs[i].get(); }
- void AddSpecs(GoASTSpec *specs) {
- m_specs.push_back(std::unique_ptr<GoASTSpec>(specs));
- }
-
-private:
- friend class GoASTNode;
- TokenType m_tok;
- std::vector<std::unique_ptr<GoASTSpec>> m_specs;
-
- GoASTGenDecl(const GoASTGenDecl &) = delete;
- const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete;
-};
-
-class GoASTGoStmt : public GoASTStmt {
-public:
- explicit GoASTGoStmt(GoASTCallExpr *call)
- : GoASTStmt(eGoStmt), m_call_up(call) {}
- ~GoASTGoStmt() override = default;
-
- const char *GetKindName() const override { return "GoStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eGoStmt; }
-
- const GoASTCallExpr *GetCall() const { return m_call_up.get(); }
- void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTCallExpr> m_call_up;
-
- GoASTGoStmt(const GoASTGoStmt &) = delete;
- const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete;
-};
-
-class GoASTIfStmt : public GoASTStmt {
-public:
- GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body,
- GoASTStmt *els)
- : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body),
- m_els_up(els) {}
- ~GoASTIfStmt() override = default;
-
- const char *GetKindName() const override { return "IfStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eIfStmt; }
-
- const GoASTStmt *GetInit() const { return m_init_up.get(); }
- void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
-
- const GoASTExpr *GetCond() const { return m_cond_up.get(); }
- void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
- const GoASTStmt *GetEls() const { return m_els_up.get(); }
- void SetEls(GoASTStmt *els) { m_els_up.reset(els); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_cond_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
- std::unique_ptr<GoASTStmt> m_els_up;
-
- GoASTIfStmt(const GoASTIfStmt &) = delete;
- const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete;
-};
-
-class GoASTImportSpec : public GoASTSpec {
-public:
- GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path)
- : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {}
- ~GoASTImportSpec() override = default;
-
- const char *GetKindName() const override { return "ImportSpec"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eImportSpec;
- }
-
- const GoASTIdent *GetName() const { return m_name_up.get(); }
- void SetName(GoASTIdent *name) { m_name_up.reset(name); }
-
- const GoASTBasicLit *GetPath() const { return m_path_up.get(); }
- void SetPath(GoASTBasicLit *path) { m_path_up.reset(path); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTBasicLit> m_path_up;
-
- GoASTImportSpec(const GoASTImportSpec &) = delete;
- const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete;
-};
-
-class GoASTIncDecStmt : public GoASTStmt {
-public:
- GoASTIncDecStmt(GoASTExpr *x, TokenType tok)
- : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {}
- ~GoASTIncDecStmt() override = default;
-
- const char *GetKindName() const override { return "IncDecStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eIncDecStmt;
- }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- TokenType GetTok() const { return m_tok; }
- void SetTok(TokenType tok) { m_tok = tok; }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- TokenType m_tok;
-
- GoASTIncDecStmt(const GoASTIncDecStmt &) = delete;
- const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete;
-};
-
-class GoASTIndexExpr : public GoASTExpr {
-public:
- GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index)
- : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {}
- ~GoASTIndexExpr() override = default;
-
- const char *GetKindName() const override { return "IndexExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eIndexExpr; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTExpr *GetIndex() const { return m_index_up.get(); }
- void SetIndex(GoASTExpr *index) { m_index_up.reset(index); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_index_up;
-
- GoASTIndexExpr(const GoASTIndexExpr &) = delete;
- const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete;
-};
-
-class GoASTInterfaceType : public GoASTExpr {
-public:
- explicit GoASTInterfaceType(GoASTFieldList *methods)
- : GoASTExpr(eInterfaceType), m_methods_up(methods) {}
- ~GoASTInterfaceType() override = default;
-
- const char *GetKindName() const override { return "InterfaceType"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eInterfaceType;
- }
-
- const GoASTFieldList *GetMethods() const { return m_methods_up.get(); }
- void SetMethods(GoASTFieldList *methods) { m_methods_up.reset(methods); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_methods_up;
-
- GoASTInterfaceType(const GoASTInterfaceType &) = delete;
- const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete;
-};
-
-class GoASTKeyValueExpr : public GoASTExpr {
-public:
- GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value)
- : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {}
- ~GoASTKeyValueExpr() override = default;
-
- const char *GetKindName() const override { return "KeyValueExpr"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eKeyValueExpr;
- }
-
- const GoASTExpr *GetKey() const { return m_key_up.get(); }
- void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
-
- const GoASTExpr *GetValue() const { return m_value_up.get(); }
- void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
-
- GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete;
- const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete;
-};
-
-class GoASTLabeledStmt : public GoASTStmt {
-public:
- GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt)
- : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {}
- ~GoASTLabeledStmt() override = default;
-
- const char *GetKindName() const override { return "LabeledStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eLabeledStmt;
- }
-
- const GoASTIdent *GetLabel() const { return m_label_up.get(); }
- void SetLabel(GoASTIdent *label) { m_label_up.reset(label); }
-
- const GoASTStmt *GetStmt() const { return m_stmt_up.get(); }
- void SetStmt(GoASTStmt *stmt) { m_stmt_up.reset(stmt); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_label_up;
- std::unique_ptr<GoASTStmt> m_stmt_up;
-
- GoASTLabeledStmt(const GoASTLabeledStmt &) = delete;
- const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete;
-};
-
-class GoASTMapType : public GoASTExpr {
-public:
- GoASTMapType(GoASTExpr *key, GoASTExpr *value)
- : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {}
- ~GoASTMapType() override = default;
-
- const char *GetKindName() const override { return "MapType"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eMapType; }
-
- const GoASTExpr *GetKey() const { return m_key_up.get(); }
- void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
-
- const GoASTExpr *GetValue() const { return m_value_up.get(); }
- void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
-
- GoASTMapType(const GoASTMapType &) = delete;
- const GoASTMapType &operator=(const GoASTMapType &) = delete;
-};
-
-class GoASTParenExpr : public GoASTExpr {
-public:
- explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {}
- ~GoASTParenExpr() override = default;
-
- const char *GetKindName() const override { return "ParenExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eParenExpr; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
-
- GoASTParenExpr(const GoASTParenExpr &) = delete;
- const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete;
-};
-
-class GoASTRangeStmt : public GoASTStmt {
-public:
- GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x,
- GoASTBlockStmt *body)
- : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value),
- m_define(define), m_x_up(x), m_body_up(body) {}
- ~GoASTRangeStmt() override = default;
-
- const char *GetKindName() const override { return "RangeStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eRangeStmt; }
-
- const GoASTExpr *GetKey() const { return m_key_up.get(); }
- void SetKey(GoASTExpr *key) { m_key_up.reset(key); }
-
- const GoASTExpr *GetValue() const { return m_value_up.get(); }
- void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
-
- bool GetDefine() const { return m_define; }
- void SetDefine(bool define) { m_define = define; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_key_up;
- std::unique_ptr<GoASTExpr> m_value_up;
- bool m_define;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTRangeStmt(const GoASTRangeStmt &) = delete;
- const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete;
-};
-
-class GoASTReturnStmt : public GoASTStmt {
-public:
- GoASTReturnStmt() : GoASTStmt(eReturnStmt) {}
- ~GoASTReturnStmt() override = default;
-
- const char *GetKindName() const override { return "ReturnStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eReturnStmt;
- }
-
- size_t NumResults() const { return m_results.size(); }
- const GoASTExpr *GetResults(int i) const { return m_results[i].get(); }
- void AddResults(GoASTExpr *results) {
- m_results.push_back(std::unique_ptr<GoASTExpr>(results));
- }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTExpr>> m_results;
-
- GoASTReturnStmt(const GoASTReturnStmt &) = delete;
- const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete;
-};
-
-class GoASTSelectStmt : public GoASTStmt {
-public:
- explicit GoASTSelectStmt(GoASTBlockStmt *body)
- : GoASTStmt(eSelectStmt), m_body_up(body) {}
- ~GoASTSelectStmt() override = default;
-
- const char *GetKindName() const override { return "SelectStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eSelectStmt;
- }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTSelectStmt(const GoASTSelectStmt &) = delete;
- const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete;
-};
-
-class GoASTSelectorExpr : public GoASTExpr {
-public:
- GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel)
- : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {}
- ~GoASTSelectorExpr() override = default;
-
- const char *GetKindName() const override { return "SelectorExpr"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eSelectorExpr;
- }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTIdent *GetSel() const { return m_sel_up.get(); }
- void SetSel(GoASTIdent *sel) { m_sel_up.reset(sel); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTIdent> m_sel_up;
-
- GoASTSelectorExpr(const GoASTSelectorExpr &) = delete;
- const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete;
-};
-
-class GoASTSendStmt : public GoASTStmt {
-public:
- GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value)
- : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {}
- ~GoASTSendStmt() override = default;
-
- const char *GetKindName() const override { return "SendStmt"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eSendStmt; }
-
- const GoASTExpr *GetChan() const { return m_chan_up.get(); }
- void SetChan(GoASTExpr *chan) { m_chan_up.reset(chan); }
-
- const GoASTExpr *GetValue() const { return m_value_up.get(); }
- void SetValue(GoASTExpr *value) { m_value_up.reset(value); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_chan_up;
- std::unique_ptr<GoASTExpr> m_value_up;
-
- GoASTSendStmt(const GoASTSendStmt &) = delete;
- const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete;
-};
-
-class GoASTSliceExpr : public GoASTExpr {
-public:
- GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max,
- bool slice3)
- : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high),
- m_max_up(max), m_slice3(slice3) {}
- ~GoASTSliceExpr() override = default;
-
- const char *GetKindName() const override { return "SliceExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eSliceExpr; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTExpr *GetLow() const { return m_low_up.get(); }
- void SetLow(GoASTExpr *low) { m_low_up.reset(low); }
-
- const GoASTExpr *GetHigh() const { return m_high_up.get(); }
- void SetHigh(GoASTExpr *high) { m_high_up.reset(high); }
-
- const GoASTExpr *GetMax() const { return m_max_up.get(); }
- void SetMax(GoASTExpr *max) { m_max_up.reset(max); }
-
- bool GetSlice3() const { return m_slice3; }
- void SetSlice3(bool slice3) { m_slice3 = slice3; }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_low_up;
- std::unique_ptr<GoASTExpr> m_high_up;
- std::unique_ptr<GoASTExpr> m_max_up;
- bool m_slice3;
-
- GoASTSliceExpr(const GoASTSliceExpr &) = delete;
- const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete;
-};
-
-class GoASTStarExpr : public GoASTExpr {
-public:
- explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {}
- ~GoASTStarExpr() override = default;
-
- const char *GetKindName() const override { return "StarExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eStarExpr; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
-
- GoASTStarExpr(const GoASTStarExpr &) = delete;
- const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete;
-};
-
-class GoASTStructType : public GoASTExpr {
-public:
- explicit GoASTStructType(GoASTFieldList *fields)
- : GoASTExpr(eStructType), m_fields_up(fields) {}
- ~GoASTStructType() override = default;
-
- const char *GetKindName() const override { return "StructType"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eStructType;
- }
-
- const GoASTFieldList *GetFields() const { return m_fields_up.get(); }
- void SetFields(GoASTFieldList *fields) { m_fields_up.reset(fields); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTFieldList> m_fields_up;
-
- GoASTStructType(const GoASTStructType &) = delete;
- const GoASTStructType &operator=(const GoASTStructType &) = delete;
-};
-
-class GoASTSwitchStmt : public GoASTStmt {
-public:
- GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body)
- : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag),
- m_body_up(body) {}
- ~GoASTSwitchStmt() override = default;
-
- const char *GetKindName() const override { return "SwitchStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eSwitchStmt;
- }
-
- const GoASTStmt *GetInit() const { return m_init_up.get(); }
- void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
-
- const GoASTExpr *GetTag() const { return m_tag_up.get(); }
- void SetTag(GoASTExpr *tag) { m_tag_up.reset(tag); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTExpr> m_tag_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTSwitchStmt(const GoASTSwitchStmt &) = delete;
- const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete;
-};
-
-class GoASTTypeAssertExpr : public GoASTExpr {
-public:
- GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type)
- : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {}
- ~GoASTTypeAssertExpr() override = default;
-
- const char *GetKindName() const override { return "TypeAssertExpr"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eTypeAssertExpr;
- }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
- const GoASTExpr *GetType() const { return m_type_up.get(); }
- void SetType(GoASTExpr *type) { m_type_up.reset(type); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTExpr> m_x_up;
- std::unique_ptr<GoASTExpr> m_type_up;
-
- GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete;
- const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete;
-};
-
-class GoASTTypeSpec : public GoASTSpec {
-public:
- GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type)
- : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {}
- ~GoASTTypeSpec() override = default;
-
- const char *GetKindName() const override { return "TypeSpec"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eTypeSpec; }
-
- const GoASTIdent *GetName() const { return m_name_up.get(); }
- void SetName(GoASTIdent *name) { m_name_up.reset(name); }
-
- const GoASTExpr *GetType() const { return m_type_up.get(); }
- void SetType(GoASTExpr *type) { m_type_up.reset(type); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTIdent> m_name_up;
- std::unique_ptr<GoASTExpr> m_type_up;
-
- GoASTTypeSpec(const GoASTTypeSpec &) = delete;
- const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete;
-};
-
-class GoASTTypeSwitchStmt : public GoASTStmt {
-public:
- GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body)
- : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign),
- m_body_up(body) {}
- ~GoASTTypeSwitchStmt() override = default;
-
- const char *GetKindName() const override { return "TypeSwitchStmt"; }
-
- static bool classof(const GoASTNode *n) {
- return n->GetKind() == eTypeSwitchStmt;
- }
-
- const GoASTStmt *GetInit() const { return m_init_up.get(); }
- void SetInit(GoASTStmt *init) { m_init_up.reset(init); }
-
- const GoASTStmt *GetAssign() const { return m_assign_up.get(); }
- void SetAssign(GoASTStmt *assign) { m_assign_up.reset(assign); }
-
- const GoASTBlockStmt *GetBody() const { return m_body_up.get(); }
- void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); }
-
-private:
- friend class GoASTNode;
- std::unique_ptr<GoASTStmt> m_init_up;
- std::unique_ptr<GoASTStmt> m_assign_up;
- std::unique_ptr<GoASTBlockStmt> m_body_up;
-
- GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete;
- const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete;
-};
-
-class GoASTUnaryExpr : public GoASTExpr {
-public:
- GoASTUnaryExpr(TokenType op, GoASTExpr *x)
- : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {}
- ~GoASTUnaryExpr() override = default;
-
- const char *GetKindName() const override { return "UnaryExpr"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eUnaryExpr; }
-
- TokenType GetOp() const { return m_op; }
- void SetOp(TokenType op) { m_op = op; }
-
- const GoASTExpr *GetX() const { return m_x_up.get(); }
- void SetX(GoASTExpr *x) { m_x_up.reset(x); }
-
-private:
- friend class GoASTNode;
- TokenType m_op;
- std::unique_ptr<GoASTExpr> m_x_up;
-
- GoASTUnaryExpr(const GoASTUnaryExpr &) = delete;
- const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete;
-};
-
-class GoASTValueSpec : public GoASTSpec {
-public:
- GoASTValueSpec() : GoASTSpec(eValueSpec) {}
- ~GoASTValueSpec() override = default;
-
- const char *GetKindName() const override { return "ValueSpec"; }
-
- static bool classof(const GoASTNode *n) { return n->GetKind() == eValueSpec; }
-
- size_t NumNames() const { return m_names.size(); }
- const GoASTIdent *GetNames(int i) const { return m_names[i].get(); }
- void AddNames(GoASTIdent *names) {
- m_names.push_back(std::unique_ptr<GoASTIdent>(names));
- }
-
- const GoASTExpr *GetType() const { return m_type_up.get(); }
- void SetType(GoASTExpr *type) { m_type_up.reset(type); }
-
- size_t NumValues() const { return m_values.size(); }
- const GoASTExpr *GetValues(int i) const { return m_values[i].get(); }
- void AddValues(GoASTExpr *values) {
- m_values.push_back(std::unique_ptr<GoASTExpr>(values));
- }
-
-private:
- friend class GoASTNode;
- std::vector<std::unique_ptr<GoASTIdent>> m_names;
- std::unique_ptr<GoASTExpr> m_type_up;
- std::vector<std::unique_ptr<GoASTExpr>> m_values;
-
- GoASTValueSpec(const GoASTValueSpec &) = delete;
- const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete;
-};
-
-template <typename R, typename V> R GoASTDecl::Visit(V *v) const {
- switch (GetKind()) {
- case eBadDecl:
- return v->VisitBadDecl(llvm::cast<const GoASTBadDecl>(this));
- case eFuncDecl:
- return v->VisitFuncDecl(llvm::cast<const GoASTFuncDecl>(this));
- case eGenDecl:
- return v->VisitGenDecl(llvm::cast<const GoASTGenDecl>(this));
- default:
- assert(false && "Invalid kind");
- }
-}
-
-template <typename R, typename V> R GoASTExpr::Visit(V *v) const {
- switch (GetKind()) {
- case eArrayType:
- return v->VisitArrayType(llvm::cast<const GoASTArrayType>(this));
- case eBadExpr:
- return v->VisitBadExpr(llvm::cast<const GoASTBadExpr>(this));
- case eBasicLit:
- return v->VisitBasicLit(llvm::cast<const GoASTBasicLit>(this));
- case eBinaryExpr:
- return v->VisitBinaryExpr(llvm::cast<const GoASTBinaryExpr>(this));
- case eIdent:
- return v->VisitIdent(llvm::cast<const GoASTIdent>(this));
- case eCallExpr:
- return v->VisitCallExpr(llvm::cast<const GoASTCallExpr>(this));
- case eChanType:
- return v->VisitChanType(llvm::cast<const GoASTChanType>(this));
- case eCompositeLit:
- return v->VisitCompositeLit(llvm::cast<const GoASTCompositeLit>(this));
- case eEllipsis:
- return v->VisitEllipsis(llvm::cast<const GoASTEllipsis>(this));
- case eFuncType:
- return v->VisitFuncType(llvm::cast<const GoASTFuncType>(this));
- case eFuncLit:
- return v->VisitFuncLit(llvm::cast<const GoASTFuncLit>(this));
- case eIndexExpr:
- return v->VisitIndexExpr(llvm::cast<const GoASTIndexExpr>(this));
- case eInterfaceType:
- return v->VisitInterfaceType(llvm::cast<const GoASTInterfaceType>(this));
- case eKeyValueExpr:
- return v->VisitKeyValueExpr(llvm::cast<const GoASTKeyValueExpr>(this));
- case eMapType:
- return v->VisitMapType(llvm::cast<const GoASTMapType>(this));
- case eParenExpr:
- return v->VisitParenExpr(llvm::cast<const GoASTParenExpr>(this));
- case eSelectorExpr:
- return v->VisitSelectorExpr(llvm::cast<const GoASTSelectorExpr>(this));
- case eSliceExpr:
- return v->VisitSliceExpr(llvm::cast<const GoASTSliceExpr>(this));
- case eStarExpr:
- return v->VisitStarExpr(llvm::cast<const GoASTStarExpr>(this));
- case eStructType:
- return v->VisitStructType(llvm::cast<const GoASTStructType>(this));
- case eTypeAssertExpr:
- return v->VisitTypeAssertExpr(llvm::cast<const GoASTTypeAssertExpr>(this));
- case eUnaryExpr:
- return v->VisitUnaryExpr(llvm::cast<const GoASTUnaryExpr>(this));
- default:
- assert(false && "Invalid kind");
- return R();
- }
-}
-
-template <typename R, typename V> R GoASTSpec::Visit(V *v) const {
- switch (GetKind()) {
- case eImportSpec:
- return v->VisitImportSpec(llvm::cast<const GoASTImportSpec>(this));
- case eTypeSpec:
- return v->VisitTypeSpec(llvm::cast<const GoASTTypeSpec>(this));
- case eValueSpec:
- return v->VisitValueSpec(llvm::cast<const GoASTValueSpec>(this));
- default:
- assert(false && "Invalid kind");
- }
-}
-
-template <typename R, typename V> R GoASTStmt::Visit(V *v) const {
- switch (GetKind()) {
- case eAssignStmt:
- return v->VisitAssignStmt(llvm::cast<const GoASTAssignStmt>(this));
- case eBadStmt:
- return v->VisitBadStmt(llvm::cast<const GoASTBadStmt>(this));
- case eBlockStmt:
- return v->VisitBlockStmt(llvm::cast<const GoASTBlockStmt>(this));
- case eBranchStmt:
- return v->VisitBranchStmt(llvm::cast<const GoASTBranchStmt>(this));
- case eCaseClause:
- return v->VisitCaseClause(llvm::cast<const GoASTCaseClause>(this));
- case eCommClause:
- return v->VisitCommClause(llvm::cast<const GoASTCommClause>(this));
- case eDeclStmt:
- return v->VisitDeclStmt(llvm::cast<const GoASTDeclStmt>(this));
- case eDeferStmt:
- return v->VisitDeferStmt(llvm::cast<const GoASTDeferStmt>(this));
- case eEmptyStmt:
- return v->VisitEmptyStmt(llvm::cast<const GoASTEmptyStmt>(this));
- case eExprStmt:
- return v->VisitExprStmt(llvm::cast<const GoASTExprStmt>(this));
- case eForStmt:
- return v->VisitForStmt(llvm::cast<const GoASTForStmt>(this));
- case eGoStmt:
- return v->VisitGoStmt(llvm::cast<const GoASTGoStmt>(this));
- case eIfStmt:
- return v->VisitIfStmt(llvm::cast<const GoASTIfStmt>(this));
- case eIncDecStmt:
- return v->VisitIncDecStmt(llvm::cast<const GoASTIncDecStmt>(this));
- case eLabeledStmt:
- return v->VisitLabeledStmt(llvm::cast<const GoASTLabeledStmt>(this));
- case eRangeStmt:
- return v->VisitRangeStmt(llvm::cast<const GoASTRangeStmt>(this));
- case eReturnStmt:
- return v->VisitReturnStmt(llvm::cast<const GoASTReturnStmt>(this));
- case eSelectStmt:
- return v->VisitSelectStmt(llvm::cast<const GoASTSelectStmt>(this));
- case eSendStmt:
- return v->VisitSendStmt(llvm::cast<const GoASTSendStmt>(this));
- case eSwitchStmt:
- return v->VisitSwitchStmt(llvm::cast<const GoASTSwitchStmt>(this));
- case eTypeSwitchStmt:
- return v->VisitTypeSwitchStmt(llvm::cast<const GoASTTypeSwitchStmt>(this));
- default:
- assert(false && "Invalid kind");
- }
-}
-
-template <typename V> void GoASTNode::WalkChildren(V &v) {
- switch (m_kind) {
-
- case eArrayType: {
- GoASTArrayType *n = llvm::cast<GoASTArrayType>(this);
- (void)n;
- v(n->m_len_up.get());
- v(n->m_elt_up.get());
- return;
- }
- case eAssignStmt: {
- GoASTAssignStmt *n = llvm::cast<GoASTAssignStmt>(this);
- (void)n;
- for (auto &e : n->m_lhs) {
- v(e.get());
- }
- for (auto &e : n->m_rhs) {
- v(e.get());
- }
- return;
- }
- case eBasicLit: {
- GoASTBasicLit *n = llvm::cast<GoASTBasicLit>(this);
- (void)n;
- return;
- }
- case eBinaryExpr: {
- GoASTBinaryExpr *n = llvm::cast<GoASTBinaryExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_y_up.get());
- return;
- }
- case eBlockStmt: {
- GoASTBlockStmt *n = llvm::cast<GoASTBlockStmt>(this);
- (void)n;
- for (auto &e : n->m_list) {
- v(e.get());
- }
- return;
- }
- case eIdent: {
- GoASTIdent *n = llvm::cast<GoASTIdent>(this);
- (void)n;
- return;
- }
- case eBranchStmt: {
- GoASTBranchStmt *n = llvm::cast<GoASTBranchStmt>(this);
- (void)n;
- v(n->m_label_up.get());
- return;
- }
- case eCallExpr: {
- GoASTCallExpr *n = llvm::cast<GoASTCallExpr>(this);
- (void)n;
- v(n->m_fun_up.get());
- for (auto &e : n->m_args) {
- v(e.get());
- }
- return;
- }
- case eCaseClause: {
- GoASTCaseClause *n = llvm::cast<GoASTCaseClause>(this);
- (void)n;
- for (auto &e : n->m_list) {
- v(e.get());
- }
- for (auto &e : n->m_body) {
- v(e.get());
- }
- return;
- }
- case eChanType: {
- GoASTChanType *n = llvm::cast<GoASTChanType>(this);
- (void)n;
- v(n->m_value_up.get());
- return;
- }
- case eCommClause: {
- GoASTCommClause *n = llvm::cast<GoASTCommClause>(this);
- (void)n;
- v(n->m_comm_up.get());
- for (auto &e : n->m_body) {
- v(e.get());
- }
- return;
- }
- case eCompositeLit: {
- GoASTCompositeLit *n = llvm::cast<GoASTCompositeLit>(this);
- (void)n;
- v(n->m_type_up.get());
- for (auto &e : n->m_elts) {
- v(e.get());
- }
- return;
- }
- case eDeclStmt: {
- GoASTDeclStmt *n = llvm::cast<GoASTDeclStmt>(this);
- (void)n;
- v(n->m_decl_up.get());
- return;
- }
- case eDeferStmt: {
- GoASTDeferStmt *n = llvm::cast<GoASTDeferStmt>(this);
- (void)n;
- v(n->m_call_up.get());
- return;
- }
- case eEllipsis: {
- GoASTEllipsis *n = llvm::cast<GoASTEllipsis>(this);
- (void)n;
- v(n->m_elt_up.get());
- return;
- }
- case eExprStmt: {
- GoASTExprStmt *n = llvm::cast<GoASTExprStmt>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eField: {
- GoASTField *n = llvm::cast<GoASTField>(this);
- (void)n;
- for (auto &e : n->m_names) {
- v(e.get());
- }
- v(n->m_type_up.get());
- v(n->m_tag_up.get());
- return;
- }
- case eFieldList: {
- GoASTFieldList *n = llvm::cast<GoASTFieldList>(this);
- (void)n;
- for (auto &e : n->m_list) {
- v(e.get());
- }
- return;
- }
- case eForStmt: {
- GoASTForStmt *n = llvm::cast<GoASTForStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_cond_up.get());
- v(n->m_post_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eFuncType: {
- GoASTFuncType *n = llvm::cast<GoASTFuncType>(this);
- (void)n;
- v(n->m_params_up.get());
- v(n->m_results_up.get());
- return;
- }
- case eFuncDecl: {
- GoASTFuncDecl *n = llvm::cast<GoASTFuncDecl>(this);
- (void)n;
- v(n->m_recv_up.get());
- v(n->m_name_up.get());
- v(n->m_type_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eFuncLit: {
- GoASTFuncLit *n = llvm::cast<GoASTFuncLit>(this);
- (void)n;
- v(n->m_type_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eGenDecl: {
- GoASTGenDecl *n = llvm::cast<GoASTGenDecl>(this);
- (void)n;
- for (auto &e : n->m_specs) {
- v(e.get());
- }
- return;
- }
- case eGoStmt: {
- GoASTGoStmt *n = llvm::cast<GoASTGoStmt>(this);
- (void)n;
- v(n->m_call_up.get());
- return;
- }
- case eIfStmt: {
- GoASTIfStmt *n = llvm::cast<GoASTIfStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_cond_up.get());
- v(n->m_body_up.get());
- v(n->m_els_up.get());
- return;
- }
- case eImportSpec: {
- GoASTImportSpec *n = llvm::cast<GoASTImportSpec>(this);
- (void)n;
- v(n->m_name_up.get());
- v(n->m_path_up.get());
- return;
- }
- case eIncDecStmt: {
- GoASTIncDecStmt *n = llvm::cast<GoASTIncDecStmt>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eIndexExpr: {
- GoASTIndexExpr *n = llvm::cast<GoASTIndexExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_index_up.get());
- return;
- }
- case eInterfaceType: {
- GoASTInterfaceType *n = llvm::cast<GoASTInterfaceType>(this);
- (void)n;
- v(n->m_methods_up.get());
- return;
- }
- case eKeyValueExpr: {
- GoASTKeyValueExpr *n = llvm::cast<GoASTKeyValueExpr>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eLabeledStmt: {
- GoASTLabeledStmt *n = llvm::cast<GoASTLabeledStmt>(this);
- (void)n;
- v(n->m_label_up.get());
- v(n->m_stmt_up.get());
- return;
- }
- case eMapType: {
- GoASTMapType *n = llvm::cast<GoASTMapType>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eParenExpr: {
- GoASTParenExpr *n = llvm::cast<GoASTParenExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eRangeStmt: {
- GoASTRangeStmt *n = llvm::cast<GoASTRangeStmt>(this);
- (void)n;
- v(n->m_key_up.get());
- v(n->m_value_up.get());
- v(n->m_x_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eReturnStmt: {
- GoASTReturnStmt *n = llvm::cast<GoASTReturnStmt>(this);
- (void)n;
- for (auto &e : n->m_results) {
- v(e.get());
- }
- return;
- }
- case eSelectStmt: {
- GoASTSelectStmt *n = llvm::cast<GoASTSelectStmt>(this);
- (void)n;
- v(n->m_body_up.get());
- return;
- }
- case eSelectorExpr: {
- GoASTSelectorExpr *n = llvm::cast<GoASTSelectorExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_sel_up.get());
- return;
- }
- case eSendStmt: {
- GoASTSendStmt *n = llvm::cast<GoASTSendStmt>(this);
- (void)n;
- v(n->m_chan_up.get());
- v(n->m_value_up.get());
- return;
- }
- case eSliceExpr: {
- GoASTSliceExpr *n = llvm::cast<GoASTSliceExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_low_up.get());
- v(n->m_high_up.get());
- v(n->m_max_up.get());
- return;
- }
- case eStarExpr: {
- GoASTStarExpr *n = llvm::cast<GoASTStarExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eStructType: {
- GoASTStructType *n = llvm::cast<GoASTStructType>(this);
- (void)n;
- v(n->m_fields_up.get());
- return;
- }
- case eSwitchStmt: {
- GoASTSwitchStmt *n = llvm::cast<GoASTSwitchStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_tag_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eTypeAssertExpr: {
- GoASTTypeAssertExpr *n = llvm::cast<GoASTTypeAssertExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- v(n->m_type_up.get());
- return;
- }
- case eTypeSpec: {
- GoASTTypeSpec *n = llvm::cast<GoASTTypeSpec>(this);
- (void)n;
- v(n->m_name_up.get());
- v(n->m_type_up.get());
- return;
- }
- case eTypeSwitchStmt: {
- GoASTTypeSwitchStmt *n = llvm::cast<GoASTTypeSwitchStmt>(this);
- (void)n;
- v(n->m_init_up.get());
- v(n->m_assign_up.get());
- v(n->m_body_up.get());
- return;
- }
- case eUnaryExpr: {
- GoASTUnaryExpr *n = llvm::cast<GoASTUnaryExpr>(this);
- (void)n;
- v(n->m_x_up.get());
- return;
- }
- case eValueSpec: {
- GoASTValueSpec *n = llvm::cast<GoASTValueSpec>(this);
- (void)n;
- for (auto &e : n->m_names) {
- v(e.get());
- }
- v(n->m_type_up.get());
- for (auto &e : n->m_values) {
- v(e.get());
- }
- return;
- }
-
- case eEmptyStmt:
- case eBadDecl:
- case eBadExpr:
- case eBadStmt:
- break;
- }
-}
-
-} // namespace lldb_private
-
-#endif
diff --git a/source/Plugins/ExpressionParser/Go/GoLexer.cpp b/source/Plugins/ExpressionParser/Go/GoLexer.cpp
deleted file mode 100644
index 63e267eaadc2..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoLexer.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-//===-- GoLexer.cpp ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <string.h>
-
-#include "GoLexer.h"
-
-using namespace lldb_private;
-
-llvm::StringMap<GoLexer::TokenType> *GoLexer::m_keywords;
-
-GoLexer::GoLexer(const char *src)
- : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "") {}
-
-bool GoLexer::SkipWhitespace() {
- bool saw_newline = false;
- for (; m_src < m_end; ++m_src) {
- if (*m_src == '\n')
- saw_newline = true;
- if (*m_src == '/' && !SkipComment())
- return saw_newline;
- else if (!IsWhitespace(*m_src))
- return saw_newline;
- }
- return saw_newline;
-}
-
-bool GoLexer::SkipComment() {
- if (m_src[0] == '/' && m_src[1] == '/') {
- for (const char *c = m_src + 2; c < m_end; ++c) {
- if (*c == '\n') {
- m_src = c - 1;
- return true;
- }
- }
- return true;
- } else if (m_src[0] == '/' && m_src[1] == '*') {
- for (const char *c = m_src + 2; c < m_end; ++c) {
- if (c[0] == '*' && c[1] == '/') {
- m_src = c + 1;
- return true;
- }
- }
- }
- return false;
-}
-
-const GoLexer::Token &GoLexer::Lex() {
- bool newline = SkipWhitespace();
- const char *start = m_src;
- m_last_token.m_type = InternalLex(newline);
- m_last_token.m_value = llvm::StringRef(start, m_src - start);
- return m_last_token;
-}
-
-GoLexer::TokenType GoLexer::InternalLex(bool newline) {
- if (m_src >= m_end) {
- return TOK_EOF;
- }
- if (newline) {
- switch (m_last_token.m_type) {
- case TOK_IDENTIFIER:
- case LIT_FLOAT:
- case LIT_IMAGINARY:
- case LIT_INTEGER:
- case LIT_RUNE:
- case LIT_STRING:
- case KEYWORD_BREAK:
- case KEYWORD_CONTINUE:
- case KEYWORD_FALLTHROUGH:
- case KEYWORD_RETURN:
- case OP_PLUS_PLUS:
- case OP_MINUS_MINUS:
- case OP_RPAREN:
- case OP_RBRACK:
- case OP_RBRACE:
- return OP_SEMICOLON;
- default:
- break;
- }
- }
- char c = *m_src;
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return DoNumber();
- case '+':
- case '-':
- case '*':
- case '/':
- case '%':
- case '&':
- case '|':
- case '^':
- case '<':
- case '>':
- case '!':
- case ':':
- case ';':
- case '(':
- case ')':
- case '[':
- case ']':
- case '{':
- case '}':
- case ',':
- case '=':
- return DoOperator();
- case '.':
- if (IsDecimal(m_src[1]))
- return DoNumber();
- return DoOperator();
- case '$':
- // For lldb persistent vars.
- return DoIdent();
- case '"':
- case '`':
- return DoString();
- case '\'':
- return DoRune();
- default:
- break;
- }
- if (IsLetterOrDigit(c))
- return DoIdent();
- ++m_src;
- return TOK_INVALID;
-}
-
-GoLexer::TokenType GoLexer::DoOperator() {
- TokenType t = TOK_INVALID;
- if (m_end - m_src > 2) {
- t = LookupKeyword(llvm::StringRef(m_src, 3));
- if (t != TOK_INVALID)
- m_src += 3;
- }
- if (t == TOK_INVALID && m_end - m_src > 1) {
- t = LookupKeyword(llvm::StringRef(m_src, 2));
- if (t != TOK_INVALID)
- m_src += 2;
- }
- if (t == TOK_INVALID) {
- t = LookupKeyword(llvm::StringRef(m_src, 1));
- ++m_src;
- }
- return t;
-}
-
-GoLexer::TokenType GoLexer::DoIdent() {
- const char *start = m_src++;
- while (m_src < m_end && IsLetterOrDigit(*m_src)) {
- ++m_src;
- }
- TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start));
- if (kw != TOK_INVALID)
- return kw;
- return TOK_IDENTIFIER;
-}
-
-GoLexer::TokenType GoLexer::DoNumber() {
- if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X')) {
- m_src += 2;
- while (IsHexChar(*m_src))
- ++m_src;
- return LIT_INTEGER;
- }
- bool dot_ok = true;
- bool e_ok = true;
- while (true) {
- while (IsDecimal(*m_src))
- ++m_src;
- switch (*m_src) {
- case 'i':
- ++m_src;
- return LIT_IMAGINARY;
- case '.':
- if (!dot_ok)
- return LIT_FLOAT;
- ++m_src;
- dot_ok = false;
- break;
- case 'e':
- case 'E':
- if (!e_ok)
- return LIT_FLOAT;
- dot_ok = e_ok = false;
- ++m_src;
- if (*m_src == '+' || *m_src == '-')
- ++m_src;
- break;
- default:
- if (dot_ok)
- return LIT_INTEGER;
- return LIT_FLOAT;
- }
- }
-}
-
-GoLexer::TokenType GoLexer::DoRune() {
- while (++m_src < m_end) {
- switch (*m_src) {
- case '\'':
- ++m_src;
- return LIT_RUNE;
- case '\n':
- return TOK_INVALID;
- case '\\':
- if (m_src[1] == '\n')
- return TOK_INVALID;
- ++m_src;
- }
- }
- return TOK_INVALID;
-}
-
-GoLexer::TokenType GoLexer::DoString() {
- if (*m_src == '`') {
- while (++m_src < m_end) {
- if (*m_src == '`') {
- ++m_src;
- return LIT_STRING;
- }
- }
- return TOK_INVALID;
- }
- while (++m_src < m_end) {
- switch (*m_src) {
- case '"':
- ++m_src;
- return LIT_STRING;
- case '\n':
- return TOK_INVALID;
- case '\\':
- if (m_src[1] == '\n')
- return TOK_INVALID;
- ++m_src;
- }
- }
- return TOK_INVALID;
-}
-
-GoLexer::TokenType GoLexer::LookupKeyword(llvm::StringRef id) {
- if (m_keywords == nullptr)
- m_keywords = InitKeywords();
- const auto &it = m_keywords->find(id);
- if (it == m_keywords->end())
- return TOK_INVALID;
- return it->second;
-}
-
-llvm::StringRef GoLexer::LookupToken(TokenType t) {
- if (m_keywords == nullptr)
- m_keywords = InitKeywords();
- for (const auto &e : *m_keywords) {
- if (e.getValue() == t)
- return e.getKey();
- }
- return "";
-}
-
-llvm::StringMap<GoLexer::TokenType> *GoLexer::InitKeywords() {
- auto &result = *new llvm::StringMap<TokenType>(128);
- result["break"] = KEYWORD_BREAK;
- result["default"] = KEYWORD_DEFAULT;
- result["func"] = KEYWORD_FUNC;
- result["interface"] = KEYWORD_INTERFACE;
- result["select"] = KEYWORD_SELECT;
- result["case"] = KEYWORD_CASE;
- result["defer"] = KEYWORD_DEFER;
- result["go"] = KEYWORD_GO;
- result["map"] = KEYWORD_MAP;
- result["struct"] = KEYWORD_STRUCT;
- result["chan"] = KEYWORD_CHAN;
- result["else"] = KEYWORD_ELSE;
- result["goto"] = KEYWORD_GOTO;
- result["package"] = KEYWORD_PACKAGE;
- result["switch"] = KEYWORD_SWITCH;
- result["const"] = KEYWORD_CONST;
- result["fallthrough"] = KEYWORD_FALLTHROUGH;
- result["if"] = KEYWORD_IF;
- result["range"] = KEYWORD_RANGE;
- result["type"] = KEYWORD_TYPE;
- result["continue"] = KEYWORD_CONTINUE;
- result["for"] = KEYWORD_FOR;
- result["import"] = KEYWORD_IMPORT;
- result["return"] = KEYWORD_RETURN;
- result["var"] = KEYWORD_VAR;
- result["+"] = OP_PLUS;
- result["-"] = OP_MINUS;
- result["*"] = OP_STAR;
- result["/"] = OP_SLASH;
- result["%"] = OP_PERCENT;
- result["&"] = OP_AMP;
- result["|"] = OP_PIPE;
- result["^"] = OP_CARET;
- result["<<"] = OP_LSHIFT;
- result[">>"] = OP_RSHIFT;
- result["&^"] = OP_AMP_CARET;
- result["+="] = OP_PLUS_EQ;
- result["-="] = OP_MINUS_EQ;
- result["*="] = OP_STAR_EQ;
- result["/="] = OP_SLASH_EQ;
- result["%="] = OP_PERCENT_EQ;
- result["&="] = OP_AMP_EQ;
- result["|="] = OP_PIPE_EQ;
- result["^="] = OP_CARET_EQ;
- result["<<="] = OP_LSHIFT_EQ;
- result[">>="] = OP_RSHIFT_EQ;
- result["&^="] = OP_AMP_CARET_EQ;
- result["&&"] = OP_AMP_AMP;
- result["||"] = OP_PIPE_PIPE;
- result["<-"] = OP_LT_MINUS;
- result["++"] = OP_PLUS_PLUS;
- result["--"] = OP_MINUS_MINUS;
- result["=="] = OP_EQ_EQ;
- result["<"] = OP_LT;
- result[">"] = OP_GT;
- result["="] = OP_EQ;
- result["!"] = OP_BANG;
- result["!="] = OP_BANG_EQ;
- result["<="] = OP_LT_EQ;
- result[">="] = OP_GT_EQ;
- result[":="] = OP_COLON_EQ;
- result["..."] = OP_DOTS;
- result["("] = OP_LPAREN;
- result["["] = OP_LBRACK;
- result["{"] = OP_LBRACE;
- result[","] = OP_COMMA;
- result["."] = OP_DOT;
- result[")"] = OP_RPAREN;
- result["]"] = OP_RBRACK;
- result["}"] = OP_RBRACE;
- result[";"] = OP_SEMICOLON;
- result[":"] = OP_COLON;
- return &result;
-}
diff --git a/source/Plugins/ExpressionParser/Go/GoLexer.h b/source/Plugins/ExpressionParser/Go/GoLexer.h
deleted file mode 100644
index f0b5b336fbe9..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoLexer.h
+++ /dev/null
@@ -1,181 +0,0 @@
-//===-- GoLexer.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_GoLexer_h
-#define liblldb_GoLexer_h
-
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace lldb_private {
-
-class GoLexer {
-public:
- explicit GoLexer(const char *src);
-
- enum TokenType {
- TOK_EOF,
- TOK_INVALID,
- TOK_IDENTIFIER,
- LIT_INTEGER,
- LIT_FLOAT,
- LIT_IMAGINARY,
- LIT_RUNE,
- LIT_STRING,
- KEYWORD_BREAK,
- KEYWORD_DEFAULT,
- KEYWORD_FUNC,
- KEYWORD_INTERFACE,
- KEYWORD_SELECT,
- KEYWORD_CASE,
- KEYWORD_DEFER,
- KEYWORD_GO,
- KEYWORD_MAP,
- KEYWORD_STRUCT,
- KEYWORD_CHAN,
- KEYWORD_ELSE,
- KEYWORD_GOTO,
- KEYWORD_PACKAGE,
- KEYWORD_SWITCH,
- KEYWORD_CONST,
- KEYWORD_FALLTHROUGH,
- KEYWORD_IF,
- KEYWORD_RANGE,
- KEYWORD_TYPE,
- KEYWORD_CONTINUE,
- KEYWORD_FOR,
- KEYWORD_IMPORT,
- KEYWORD_RETURN,
- KEYWORD_VAR,
- OP_PLUS,
- OP_MINUS,
- OP_STAR,
- OP_SLASH,
- OP_PERCENT,
- OP_AMP,
- OP_PIPE,
- OP_CARET,
- OP_LSHIFT,
- OP_RSHIFT,
- OP_AMP_CARET,
- OP_PLUS_EQ,
- OP_MINUS_EQ,
- OP_STAR_EQ,
- OP_SLASH_EQ,
- OP_PERCENT_EQ,
- OP_AMP_EQ,
- OP_PIPE_EQ,
- OP_CARET_EQ,
- OP_LSHIFT_EQ,
- OP_RSHIFT_EQ,
- OP_AMP_CARET_EQ,
- OP_AMP_AMP,
- OP_PIPE_PIPE,
- OP_LT_MINUS,
- OP_PLUS_PLUS,
- OP_MINUS_MINUS,
- OP_EQ_EQ,
- OP_LT,
- OP_GT,
- OP_EQ,
- OP_BANG,
- OP_BANG_EQ,
- OP_LT_EQ,
- OP_GT_EQ,
- OP_COLON_EQ,
- OP_DOTS,
- OP_LPAREN,
- OP_LBRACK,
- OP_LBRACE,
- OP_COMMA,
- OP_DOT,
- OP_RPAREN,
- OP_RBRACK,
- OP_RBRACE,
- OP_SEMICOLON,
- OP_COLON,
- };
-
- struct Token {
- explicit Token(TokenType t, llvm::StringRef text)
- : m_type(t), m_value(text) {}
- TokenType m_type;
- llvm::StringRef m_value;
- };
-
- const Token &Lex();
-
- size_t BytesRemaining() const { return m_end - m_src; }
- llvm::StringRef GetString(int len) const {
- return llvm::StringRef(m_src, len);
- }
-
- static TokenType LookupKeyword(llvm::StringRef id);
- static llvm::StringRef LookupToken(TokenType t);
-
-private:
- bool IsDecimal(char c) { return c >= '0' && c <= '9'; }
- bool IsHexChar(char c) {
- if (c >= '0' && c <= '9')
- return true;
- if (c >= 'A' && c <= 'F')
- return true;
- if (c >= 'a' && c <= 'f')
- return true;
- return false;
- }
- bool IsLetterOrDigit(char c) {
- if (c >= 'a' && c <= 'z')
- return true;
- if (c >= 'A' && c <= 'Z')
- return true;
- if (c == '_')
- return true;
- if (c >= '0' && c <= '9')
- return true;
- // Treat all non-ascii chars as letters for simplicity.
- return 0 != (c & 0x80);
- }
- bool IsWhitespace(char c) {
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- return true;
- }
- return false;
- }
-
- bool SkipWhitespace();
- bool SkipComment();
-
- TokenType InternalLex(bool newline);
-
- TokenType DoOperator();
-
- TokenType DoIdent();
-
- TokenType DoNumber();
-
- TokenType DoRune();
-
- TokenType DoString();
-
- static llvm::StringMap<TokenType> *InitKeywords();
-
- static llvm::StringMap<TokenType> *m_keywords;
-
- const char *m_src;
- const char *m_end;
- Token m_last_token;
-};
-
-} // namespace lldb_private
-
-#endif
diff --git a/source/Plugins/ExpressionParser/Go/GoParser.cpp b/source/Plugins/ExpressionParser/Go/GoParser.cpp
deleted file mode 100644
index 9c845d02bca0..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoParser.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-//===-- GoParser.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <vector>
-
-#include "GoParser.h"
-
-#include "Plugins/ExpressionParser/Go/GoAST.h"
-#include "lldb/Utility/Status.h"
-#include "llvm/ADT/SmallString.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-namespace {
-llvm::StringRef DescribeToken(GoLexer::TokenType t) {
- switch (t) {
- case GoLexer::TOK_EOF:
- return "<eof>";
- case GoLexer::TOK_IDENTIFIER:
- return "identifier";
- case GoLexer::LIT_FLOAT:
- return "float";
- case GoLexer::LIT_IMAGINARY:
- return "imaginary";
- case GoLexer::LIT_INTEGER:
- return "integer";
- case GoLexer::LIT_RUNE:
- return "rune";
- case GoLexer::LIT_STRING:
- return "string";
- default:
- return GoLexer::LookupToken(t);
- }
-}
-} // namespace
-
-class GoParser::Rule {
-public:
- Rule(llvm::StringRef name, GoParser *p)
- : m_name(name), m_parser(p), m_pos(p->m_pos) {}
-
- std::nullptr_t error() {
- if (!m_parser->m_failed) {
- // Set m_error in case this is the top level.
- if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
- m_parser->m_error = m_parser->m_last;
- else
- m_parser->m_error = DescribeToken(m_parser->m_last_tok);
- // And set m_last in case it isn't.
- m_parser->m_last = m_name;
- m_parser->m_last_tok = GoLexer::TOK_INVALID;
- m_parser->m_pos = m_pos;
- }
- return nullptr;
- }
-
-private:
- llvm::StringRef m_name;
- GoParser *m_parser;
- size_t m_pos;
-};
-
-GoParser::GoParser(const char *src)
- : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID),
- m_failed(false) {}
-
-GoASTStmt *GoParser::Statement() {
- Rule r("Statement", this);
- GoLexer::TokenType t = peek();
- GoASTStmt *ret = nullptr;
- switch (t) {
- case GoLexer::TOK_EOF:
- case GoLexer::OP_SEMICOLON:
- case GoLexer::OP_RPAREN:
- case GoLexer::OP_RBRACE:
- case GoLexer::TOK_INVALID:
- return EmptyStmt();
- case GoLexer::OP_LBRACE:
- return Block();
-
- /* TODO:
-case GoLexer::KEYWORD_GO:
- return GoStmt();
-case GoLexer::KEYWORD_RETURN:
- return ReturnStmt();
-case GoLexer::KEYWORD_BREAK:
-case GoLexer::KEYWORD_CONTINUE:
-case GoLexer::KEYWORD_GOTO:
-case GoLexer::KEYWORD_FALLTHROUGH:
- return BranchStmt();
-case GoLexer::KEYWORD_IF:
- return IfStmt();
-case GoLexer::KEYWORD_SWITCH:
- return SwitchStmt();
-case GoLexer::KEYWORD_SELECT:
- return SelectStmt();
-case GoLexer::KEYWORD_FOR:
- return ForStmt();
-case GoLexer::KEYWORD_DEFER:
- return DeferStmt();
-case GoLexer::KEYWORD_CONST:
-case GoLexer::KEYWORD_TYPE:
-case GoLexer::KEYWORD_VAR:
- return DeclStmt();
-case GoLexer::TOK_IDENTIFIER:
- if ((ret = LabeledStmt()) ||
- (ret = ShortVarDecl()))
- {
- return ret;
- }
-*/
- default:
- break;
- }
- GoASTExpr *expr = Expression();
- if (expr == nullptr)
- return r.error();
- if (/*(ret = SendStmt(expr)) ||*/
- (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) ||
- (ret = ExpressionStmt(expr))) {
- return ret;
- }
- delete expr;
- return r.error();
-}
-
-GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) {
- if (Semicolon())
- return new GoASTExprStmt(e);
- return nullptr;
-}
-
-GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) {
- Rule r("IncDecStmt", this);
- if (match(GoLexer::OP_PLUS_PLUS))
- return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS)
- : r.error();
- if (match(GoLexer::OP_MINUS_MINUS))
- return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS)
- : r.error();
- return nullptr;
-}
-
-GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) {
- Rule r("Assignment", this);
- std::vector<std::unique_ptr<GoASTExpr>> lhs;
- for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
- lhs.push_back(std::unique_ptr<GoASTExpr>(l));
- switch (peek()) {
- case GoLexer::OP_EQ:
- case GoLexer::OP_PLUS_EQ:
- case GoLexer::OP_MINUS_EQ:
- case GoLexer::OP_PIPE_EQ:
- case GoLexer::OP_CARET_EQ:
- case GoLexer::OP_STAR_EQ:
- case GoLexer::OP_SLASH_EQ:
- case GoLexer::OP_PERCENT_EQ:
- case GoLexer::OP_LSHIFT_EQ:
- case GoLexer::OP_RSHIFT_EQ:
- case GoLexer::OP_AMP_EQ:
- case GoLexer::OP_AMP_CARET_EQ:
- break;
- default:
- return r.error();
- }
- // We don't want to own e until we know this is an assignment.
- std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
- stmt->AddLhs(e);
- for (auto &l : lhs)
- stmt->AddLhs(l.release());
- for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
- stmt->AddRhs(r);
- if (!Semicolon() || stmt->NumRhs() == 0)
- return new GoASTBadStmt;
- return stmt.release();
-}
-
-GoASTStmt *GoParser::EmptyStmt() {
- if (match(GoLexer::TOK_EOF))
- return nullptr;
- if (Semicolon())
- return new GoASTEmptyStmt;
- return nullptr;
-}
-
-GoASTStmt *GoParser::GoStmt() {
- if (match(GoLexer::KEYWORD_GO)) {
- if (GoASTCallExpr *e =
- llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) {
- return FinishStmt(new GoASTGoStmt(e));
- }
- m_last = "call expression";
- m_failed = true;
- return new GoASTBadStmt();
- }
- return nullptr;
-}
-
-GoASTStmt *GoParser::ReturnStmt() {
- if (match(GoLexer::KEYWORD_RETURN)) {
- std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
- for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
- r->AddResults(e);
- return FinishStmt(r.release());
- }
- return nullptr;
-}
-
-GoASTStmt *GoParser::BranchStmt() {
- GoLexer::Token *tok;
- if ((tok = match(GoLexer::KEYWORD_BREAK)) ||
- (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
- (tok = match(GoLexer::KEYWORD_GOTO))) {
- auto *e = Identifier();
- if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
- return syntaxerror();
- return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
- }
- if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
- return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
-
- return nullptr;
-}
-
-GoASTIdent *GoParser::Identifier() {
- if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
- return new GoASTIdent(*tok);
- return nullptr;
-}
-
-GoASTExpr *GoParser::MoreExpressionList() {
- if (match(GoLexer::OP_COMMA)) {
- auto *e = Expression();
- if (!e)
- return syntaxerror();
- return e;
- }
- return nullptr;
-}
-
-GoASTIdent *GoParser::MoreIdentifierList() {
- if (match(GoLexer::OP_COMMA)) {
- auto *i = Identifier();
- if (!i)
- return syntaxerror();
- return i;
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::Expression() {
- Rule r("Expression", this);
- if (GoASTExpr *ret = OrExpr())
- return ret;
- return r.error();
-}
-
-GoASTExpr *GoParser::UnaryExpr() {
- switch (peek()) {
- case GoLexer::OP_PLUS:
- case GoLexer::OP_MINUS:
- case GoLexer::OP_BANG:
- case GoLexer::OP_CARET:
- case GoLexer::OP_STAR:
- case GoLexer::OP_AMP:
- case GoLexer::OP_LT_MINUS: {
- const GoLexer::Token t = next();
- if (GoASTExpr *e = UnaryExpr()) {
- if (t.m_type == GoLexer::OP_STAR)
- return new GoASTStarExpr(e);
- else
- return new GoASTUnaryExpr(t.m_type, e);
- }
- return syntaxerror();
- }
- default:
- return PrimaryExpr();
- }
-}
-
-GoASTExpr *GoParser::OrExpr() {
- std::unique_ptr<GoASTExpr> l(AndExpr());
- if (l) {
- while (match(GoLexer::OP_PIPE_PIPE)) {
- GoASTExpr *r = AndExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::AndExpr() {
- std::unique_ptr<GoASTExpr> l(RelExpr());
- if (l) {
- while (match(GoLexer::OP_AMP_AMP)) {
- GoASTExpr *r = RelExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::RelExpr() {
- std::unique_ptr<GoASTExpr> l(AddExpr());
- if (l) {
- for (GoLexer::Token *t;
- (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
- (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
- (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = AddExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::AddExpr() {
- std::unique_ptr<GoASTExpr> l(MulExpr());
- if (l) {
- for (GoLexer::Token *t;
- (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
- (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = MulExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::MulExpr() {
- std::unique_ptr<GoASTExpr> l(UnaryExpr());
- if (l) {
- for (GoLexer::Token *t;
- (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
- (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
- (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
- (t = match(GoLexer::OP_AMP_CARET));) {
- GoLexer::TokenType op = t->m_type;
- GoASTExpr *r = UnaryExpr();
- if (r)
- l.reset(new GoASTBinaryExpr(l.release(), r, op));
- else
- return syntaxerror();
- }
- return l.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::PrimaryExpr() {
- GoASTExpr *l;
- GoASTExpr *r;
- (l = Conversion()) || (l = Operand());
- if (!l)
- return nullptr;
- while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) ||
- (r = Arguments(l))) {
- l = r;
- }
- return l;
-}
-
-GoASTExpr *GoParser::Operand() {
- GoLexer::Token *lit;
- if ((lit = match(GoLexer::LIT_INTEGER)) ||
- (lit = match(GoLexer::LIT_FLOAT)) ||
- (lit = match(GoLexer::LIT_IMAGINARY)) ||
- (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
- return new GoASTBasicLit(*lit);
- if (match(GoLexer::OP_LPAREN)) {
- GoASTExpr *e;
- if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
- return syntaxerror();
- return e;
- }
- // MethodExpr should be handled by Selector
- if (GoASTExpr *e = CompositeLit())
- return e;
- if (GoASTExpr *n = Name())
- return n;
- return FunctionLit();
-}
-
-GoASTExpr *GoParser::FunctionLit() {
- if (!match(GoLexer::KEYWORD_FUNC))
- return nullptr;
- auto *sig = Signature();
- if (!sig)
- return syntaxerror();
- auto *body = Block();
- if (!body) {
- delete sig;
- return syntaxerror();
- }
- return new GoASTFuncLit(sig, body);
-}
-
-GoASTBlockStmt *GoParser::Block() {
- if (!match(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
- for (auto *s = Statement(); s; s = Statement())
- block->AddList(s);
- if (!match(GoLexer::OP_RBRACE))
- return syntaxerror();
- return block.release();
-}
-
-GoASTExpr *GoParser::CompositeLit() {
- Rule r("CompositeLit", this);
- GoASTExpr *type;
- (type = StructType()) || (type = ArrayOrSliceType(true)) ||
- (type = MapType()) || (type = Name());
- if (!type)
- return r.error();
- GoASTCompositeLit *lit = LiteralValue();
- if (!lit) {
- delete type;
- return r.error();
- }
- lit->SetType(type);
- return lit;
-}
-
-GoASTCompositeLit *GoParser::LiteralValue() {
- if (!match(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
- for (GoASTExpr *e = Element(); e; e = Element()) {
- lit->AddElts(e);
- if (!match(GoLexer::OP_COMMA))
- break;
- }
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return lit.release();
-}
-
-GoASTExpr *GoParser::Element() {
- GoASTExpr *key;
- if (!((key = Expression()) || (key = LiteralValue())))
- return nullptr;
- if (!match(GoLexer::OP_COLON))
- return key;
- GoASTExpr *value;
- if ((value = Expression()) || (value = LiteralValue()))
- return new GoASTKeyValueExpr(key, value);
- delete key;
- return syntaxerror();
-}
-
-GoASTExpr *GoParser::Selector(GoASTExpr *e) {
- Rule r("Selector", this);
- if (match(GoLexer::OP_DOT)) {
- if (auto *name = Identifier())
- return new GoASTSelectorExpr(e, name);
- }
- return r.error();
-}
-
-GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) {
- Rule r("IndexOrSlice", this);
- if (match(GoLexer::OP_LBRACK)) {
- std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
- bool slice = false;
- if (match(GoLexer::OP_COLON)) {
- slice = true;
- i2.reset(Expression());
- if (i2 && match(GoLexer::OP_COLON)) {
- i3.reset(Expression());
- if (!i3)
- return syntaxerror();
- }
- }
- if (!(slice || i1))
- return syntaxerror();
- if (!mustMatch(GoLexer::OP_RBRACK))
- return nullptr;
- if (slice) {
- bool slice3 = i3.get();
- return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(),
- slice3);
- }
- return new GoASTIndexExpr(e, i1.release());
- }
- return r.error();
-}
-
-GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) {
- Rule r("TypeAssertion", this);
- if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) {
- if (auto *t = Type()) {
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- return new GoASTTypeAssertExpr(e, t);
- }
- return syntaxerror();
- }
- return r.error();
-}
-
-GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
- if (match(GoLexer::OP_LPAREN)) {
- std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
- GoASTExpr *arg;
- // ( ExpressionList | Type [ "," ExpressionList ] )
- for ((arg = Expression()) || (arg = Type()); arg;
- arg = MoreExpressionList()) {
- call->AddArgs(arg);
- }
- if (match(GoLexer::OP_DOTS))
- call->SetEllipsis(true);
-
- // Eat trailing comma
- match(GoLexer::OP_COMMA);
-
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- call->SetFun(e);
- return call.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::Conversion() {
- Rule r("Conversion", this);
- if (GoASTExpr *t = Type2()) {
- std::unique_ptr<GoASTExpr> owner(t);
- if (match(GoLexer::OP_LPAREN)) {
- GoASTExpr *v = Expression();
- if (!v)
- return syntaxerror();
- match(GoLexer::OP_COMMA);
- if (!mustMatch(GoLexer::OP_RPAREN))
- return r.error();
- GoASTCallExpr *call = new GoASTCallExpr(false);
- call->SetFun(t);
- owner.release();
- call->AddArgs(v);
- return call;
- }
- }
- return r.error();
-}
-
-GoASTExpr *GoParser::Type2() {
- switch (peek()) {
- case GoLexer::OP_LBRACK:
- return ArrayOrSliceType(false);
- case GoLexer::KEYWORD_STRUCT:
- return StructType();
- case GoLexer::KEYWORD_FUNC:
- return FunctionType();
- case GoLexer::KEYWORD_INTERFACE:
- return InterfaceType();
- case GoLexer::KEYWORD_MAP:
- return MapType();
- case GoLexer::KEYWORD_CHAN:
- return ChanType2();
- default:
- return nullptr;
- }
-}
-
-GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) {
- Rule r("ArrayType", this);
- if (match(GoLexer::OP_LBRACK)) {
- std::unique_ptr<GoASTExpr> len;
- if (allowEllipsis && match(GoLexer::OP_DOTS)) {
- len.reset(new GoASTEllipsis(nullptr));
- } else {
- len.reset(Expression());
- }
-
- if (!match(GoLexer::OP_RBRACK))
- return r.error();
- GoASTExpr *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTArrayType(len.release(), elem);
- }
- return r.error();
-}
-
-GoASTExpr *GoParser::StructType() {
- if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
- return nullptr;
- std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
- while (auto *field = FieldDecl())
- fields->AddList(field);
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return new GoASTStructType(fields.release());
-}
-
-GoASTField *GoParser::FieldDecl() {
- std::unique_ptr<GoASTField> f(new GoASTField);
- GoASTExpr *t = FieldNamesAndType(f.get());
- if (!t)
- t = AnonymousFieldType();
- if (!t)
- return nullptr;
-
- if (auto *tok = match(GoLexer::LIT_STRING))
- f->SetTag(new GoASTBasicLit(*tok));
- if (!Semicolon())
- return syntaxerror();
- return f.release();
-}
-
-GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) {
- Rule r("FieldNames", this);
- for (auto *id = Identifier(); id; id = MoreIdentifierList())
- field->AddNames(id);
- if (m_failed)
- return nullptr;
- GoASTExpr *t = Type();
- if (t)
- return t;
- return r.error();
-}
-
-GoASTExpr *GoParser::AnonymousFieldType() {
- bool pointer = match(GoLexer::OP_STAR);
- GoASTExpr *t = Type();
- if (!t)
- return nullptr;
- if (pointer)
- return new GoASTStarExpr(t);
- return t;
-}
-
-GoASTExpr *GoParser::FunctionType() {
- if (!match(GoLexer::KEYWORD_FUNC))
- return nullptr;
- return Signature();
-}
-
-GoASTFuncType *GoParser::Signature() {
- auto *params = Params();
- if (!params)
- return syntaxerror();
- auto *result = Params();
- if (!result) {
- if (auto *t = Type()) {
- result = new GoASTFieldList;
- auto *f = new GoASTField;
- f->SetType(t);
- result->AddList(f);
- }
- }
- return new GoASTFuncType(params, result);
-}
-
-GoASTFieldList *GoParser::Params() {
- if (!match(GoLexer::OP_LPAREN))
- return nullptr;
- std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
- while (GoASTField *p = ParamDecl()) {
- l->AddList(p);
- if (!match(GoLexer::OP_COMMA))
- break;
- }
- if (!mustMatch(GoLexer::OP_RPAREN))
- return nullptr;
- return l.release();
-}
-
-GoASTField *GoParser::ParamDecl() {
- std::unique_ptr<GoASTField> field(new GoASTField);
- GoASTIdent *id = Identifier();
- if (id) {
- // Try `IdentifierList [ "..." ] Type`.
- // If that fails, backtrack and try `[ "..." ] Type`.
- Rule r("NamedParam", this);
- for (; id; id = MoreIdentifierList())
- field->AddNames(id);
- GoASTExpr *t = ParamType();
- if (t) {
- field->SetType(t);
- return field.release();
- }
- field.reset(new GoASTField);
- r.error();
- }
- GoASTExpr *t = ParamType();
- if (t) {
- field->SetType(t);
- return field.release();
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::ParamType() {
- bool dots = match(GoLexer::OP_DOTS);
- GoASTExpr *t = Type();
- if (!dots)
- return t;
- if (!t)
- return syntaxerror();
- return new GoASTEllipsis(t);
-}
-
-GoASTExpr *GoParser::InterfaceType() {
- if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
- return nullptr;
- std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
- while (true) {
- Rule r("MethodSpec", this);
- // ( identifier Signature | TypeName ) ;
- std::unique_ptr<GoASTIdent> id(Identifier());
- if (!id)
- break;
- GoASTExpr *type = Signature();
- if (!type) {
- r.error();
- id.reset();
- type = Name();
- }
- if (!Semicolon())
- return syntaxerror();
- auto *f = new GoASTField;
- if (id)
- f->AddNames(id.release());
- f->SetType(type);
- methods->AddList(f);
- }
- if (!mustMatch(GoLexer::OP_RBRACE))
- return nullptr;
- return new GoASTInterfaceType(methods.release());
-}
-
-GoASTExpr *GoParser::MapType() {
- if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
- return nullptr;
- std::unique_ptr<GoASTExpr> key(Type());
- if (!key)
- return syntaxerror();
- if (!mustMatch(GoLexer::OP_RBRACK))
- return nullptr;
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTMapType(key.release(), elem);
-}
-
-GoASTExpr *GoParser::ChanType() {
- Rule r("chan", this);
- if (match(GoLexer::OP_LT_MINUS)) {
- if (match(GoLexer::KEYWORD_CHAN)) {
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTChanType(GoASTNode::eChanRecv, elem);
- }
- return r.error();
- }
- return ChanType2();
-}
-
-GoASTExpr *GoParser::ChanType2() {
- if (!match(GoLexer::KEYWORD_CHAN))
- return nullptr;
- auto dir = GoASTNode::eChanBidir;
- if (match(GoLexer::OP_LT_MINUS))
- dir = GoASTNode::eChanSend;
- auto *elem = Type();
- if (!elem)
- return syntaxerror();
- return new GoASTChanType(dir, elem);
-}
-
-GoASTExpr *GoParser::Type() {
- if (GoASTExpr *t = Type2())
- return t;
- if (GoASTExpr *t = Name())
- return t;
- if (GoASTExpr *t = ChanType())
- return t;
- if (match(GoLexer::OP_STAR)) {
- GoASTExpr *t = Type();
- if (!t)
- return syntaxerror();
- return new GoASTStarExpr(t);
- }
- if (match(GoLexer::OP_LPAREN)) {
- std::unique_ptr<GoASTExpr> t(Type());
- if (!t || !match(GoLexer::OP_RPAREN))
- return syntaxerror();
- return t.release();
- }
- return nullptr;
-}
-
-bool GoParser::Semicolon() {
- if (match(GoLexer::OP_SEMICOLON))
- return true;
- switch (peek()) {
- case GoLexer::OP_RPAREN:
- case GoLexer::OP_RBRACE:
- case GoLexer::TOK_EOF:
- return true;
- default:
- return false;
- }
-}
-
-GoASTExpr *GoParser::Name() {
- if (auto *id = Identifier()) {
- if (GoASTExpr *qual = QualifiedIdent(id))
- return qual;
- return id;
- }
- return nullptr;
-}
-
-GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) {
- Rule r("QualifiedIdent", this);
- llvm::SmallString<32> path(p->GetName().m_value);
- GoLexer::Token *next;
- bool have_slashes = false;
- // LLDB extension: support full/package/path.name
- while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) {
- have_slashes = true;
- path.append("/");
- path.append(next->m_value);
- }
- if (match(GoLexer::OP_DOT)) {
- auto *name = Identifier();
- if (name) {
- if (have_slashes) {
- p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
- }
- return new GoASTSelectorExpr(p, name);
- }
- }
- return r.error();
-}
-
-llvm::StringRef GoParser::CopyString(llvm::StringRef s) {
- return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
-}
-
-void GoParser::GetError(Status &error) {
- llvm::StringRef want;
- if (m_failed)
- want =
- m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
- else
- want = m_error;
- size_t len = m_lexer.BytesRemaining();
- if (len > 10)
- len = 10;
- llvm::StringRef got;
- if (len == 0)
- got = "<eof>";
- else
- got = m_lexer.GetString(len);
- error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.",
- want.str().c_str(), got.str().c_str());
-}
diff --git a/source/Plugins/ExpressionParser/Go/GoParser.h b/source/Plugins/ExpressionParser/Go/GoParser.h
deleted file mode 100644
index 9ed2ae2033bd..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoParser.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//===-- GoParser.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_GoParser_h
-#define liblldb_GoParser_h
-
-#include "Plugins/ExpressionParser/Go/GoAST.h"
-#include "Plugins/ExpressionParser/Go/GoLexer.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-class GoParser {
-public:
- explicit GoParser(const char *src);
-
- GoASTStmt *Statement();
-
- GoASTStmt *GoStmt();
- GoASTStmt *ReturnStmt();
- GoASTStmt *BranchStmt();
- GoASTStmt *EmptyStmt();
- GoASTStmt *ExpressionStmt(GoASTExpr *e);
- GoASTStmt *IncDecStmt(GoASTExpr *e);
- GoASTStmt *Assignment(GoASTExpr *e);
- GoASTBlockStmt *Block();
-
- GoASTExpr *MoreExpressionList(); // ["," Expression]
- GoASTIdent *MoreIdentifierList(); // ["," Identifier]
-
- GoASTExpr *Expression();
- GoASTExpr *UnaryExpr();
- GoASTExpr *OrExpr();
- GoASTExpr *AndExpr();
- GoASTExpr *RelExpr();
- GoASTExpr *AddExpr();
- GoASTExpr *MulExpr();
- GoASTExpr *PrimaryExpr();
- GoASTExpr *Operand();
- GoASTExpr *Conversion();
-
- GoASTExpr *Selector(GoASTExpr *e);
- GoASTExpr *IndexOrSlice(GoASTExpr *e);
- GoASTExpr *TypeAssertion(GoASTExpr *e);
- GoASTExpr *Arguments(GoASTExpr *e);
-
- GoASTExpr *Type();
- GoASTExpr *Type2();
- GoASTExpr *ArrayOrSliceType(bool allowEllipsis);
- GoASTExpr *StructType();
- GoASTExpr *FunctionType();
- GoASTExpr *InterfaceType();
- GoASTExpr *MapType();
- GoASTExpr *ChanType();
- GoASTExpr *ChanType2();
-
- GoASTExpr *Name();
- GoASTExpr *QualifiedIdent(GoASTIdent *p);
- GoASTIdent *Identifier();
-
- GoASTField *FieldDecl();
- GoASTExpr *AnonymousFieldType();
- GoASTExpr *FieldNamesAndType(GoASTField *f);
-
- GoASTFieldList *Params();
- GoASTField *ParamDecl();
- GoASTExpr *ParamType();
- GoASTFuncType *Signature();
- GoASTExpr *CompositeLit();
- GoASTExpr *FunctionLit();
- GoASTExpr *Element();
- GoASTCompositeLit *LiteralValue();
-
- bool Failed() const { return m_failed; }
- bool AtEOF() const {
- return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size();
- }
-
- void GetError(Status &error);
-
-private:
- class Rule;
- friend class Rule;
-
- std::nullptr_t syntaxerror() {
- m_failed = true;
- return nullptr;
- }
- GoLexer::Token &next() {
- if (m_pos >= m_tokens.size()) {
- if (m_pos != 0 && (m_tokens.back().m_type == GoLexer::TOK_EOF ||
- m_tokens.back().m_type == GoLexer::TOK_INVALID))
- return m_tokens.back();
- m_pos = m_tokens.size();
- m_tokens.push_back(m_lexer.Lex());
- }
- return m_tokens[m_pos++];
- }
- GoLexer::TokenType peek() {
- GoLexer::Token &tok = next();
- --m_pos;
- return tok.m_type;
- }
- GoLexer::Token *match(GoLexer::TokenType t) {
- GoLexer::Token &tok = next();
- if (tok.m_type == t)
- return &tok;
- --m_pos;
- m_last_tok = t;
- return nullptr;
- }
- GoLexer::Token *mustMatch(GoLexer::TokenType t) {
- GoLexer::Token *tok = match(t);
- if (tok)
- return tok;
- return syntaxerror();
- }
- bool Semicolon();
-
- GoASTStmt *FinishStmt(GoASTStmt *s) {
- if (!Semicolon())
- m_failed = true;
- return s;
- }
-
- llvm::StringRef CopyString(llvm::StringRef s);
-
- GoLexer m_lexer;
- std::vector<GoLexer::Token> m_tokens;
- size_t m_pos;
- llvm::StringRef m_error;
- llvm::StringRef m_last;
- GoLexer::TokenType m_last_tok;
- llvm::StringMap<uint8_t> m_strings;
- bool m_failed;
-};
-}
-
-#endif
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
deleted file mode 100644
index 3a10a1dc767a..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp
+++ /dev/null
@@ -1,668 +0,0 @@
-//===-- GoUserExpression.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-#include <stdio.h>
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-// C++ Includes
-#include <cstdlib>
-#include <memory>
-#include <string>
-#include <vector>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-
-// Project includes
-#include "GoUserExpression.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectRegister.h"
-#include "lldb/Expression/DiagnosticManager.h"
-#include "lldb/Expression/ExpressionVariable.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/TypeList.h"
-#include "lldb/Symbol/VariableList.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/ThreadPlan.h"
-#include "lldb/Target/ThreadPlanCallUserExpression.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataEncoder.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/lldb-private.h"
-
-#include "Plugins/ExpressionParser/Go/GoAST.h"
-#include "Plugins/ExpressionParser/Go/GoParser.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-class GoUserExpression::GoInterpreter {
-public:
- GoInterpreter(ExecutionContext &exe_ctx, const char *expr)
- : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr) {
- if (m_frame) {
- const SymbolContext &ctx =
- m_frame->GetSymbolContext(eSymbolContextFunction);
- ConstString fname = ctx.GetFunctionName();
- if (fname.GetLength() > 0) {
- size_t dot = fname.GetStringRef().find('.');
- if (dot != llvm::StringRef::npos)
- m_package = llvm::StringRef(fname.AsCString(), dot);
- }
- }
- }
-
- void set_use_dynamic(DynamicValueType use_dynamic) {
- m_use_dynamic = use_dynamic;
- }
-
- bool Parse();
- lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx);
- lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s);
- lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e);
-
- ValueObjectSP VisitBadExpr(const GoASTBadExpr *e) {
- m_parser.GetError(m_error);
- return nullptr;
- }
-
- ValueObjectSP VisitParenExpr(const GoASTParenExpr *e);
- ValueObjectSP VisitIdent(const GoASTIdent *e);
- ValueObjectSP VisitStarExpr(const GoASTStarExpr *e);
- ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e);
- ValueObjectSP VisitBasicLit(const GoASTBasicLit *e);
- ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e);
- ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e);
- ValueObjectSP VisitCallExpr(const GoASTCallExpr *e);
-
- ValueObjectSP VisitTypeAssertExpr(const GoASTTypeAssertExpr *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitBinaryExpr(const GoASTBinaryExpr *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitArrayType(const GoASTArrayType *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitChanType(const GoASTChanType *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitCompositeLit(const GoASTCompositeLit *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitEllipsis(const GoASTEllipsis *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitFuncType(const GoASTFuncType *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitFuncLit(const GoASTFuncLit *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitInterfaceType(const GoASTInterfaceType *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitKeyValueExpr(const GoASTKeyValueExpr *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitMapType(const GoASTMapType *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitSliceExpr(const GoASTSliceExpr *e) {
- return NotImplemented(e);
- }
-
- ValueObjectSP VisitStructType(const GoASTStructType *e) {
- return NotImplemented(e);
- }
-
- CompilerType EvaluateType(const GoASTExpr *e);
-
- Status &error() { return m_error; }
-
-private:
- std::nullptr_t NotImplemented(const GoASTExpr *e) {
- m_error.SetErrorStringWithFormat("%s node not implemented",
- e->GetKindName());
- return nullptr;
- }
-
- ExecutionContext m_exe_ctx;
- lldb::StackFrameSP m_frame;
- GoParser m_parser;
- DynamicValueType m_use_dynamic;
- Status m_error;
- llvm::StringRef m_package;
- std::vector<std::unique_ptr<GoASTStmt>> m_statements;
-};
-
-VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) {
- ConstString fullname(name.str());
- VariableList variable_list;
- if (!target) {
- return nullptr;
- }
- const uint32_t match_count =
- target->GetImages().FindGlobalVariables(fullname, 1, variable_list);
- if (match_count == 1) {
- return variable_list.GetVariableAtIndex(0);
- }
- return nullptr;
-}
-
-CompilerType LookupType(TargetSP target, ConstString name) {
- if (!target)
- return CompilerType();
- SymbolContext sc;
- TypeList type_list;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- uint32_t num_matches = target->GetImages().FindTypes(
- sc, name, false, 2, searched_symbol_files, type_list);
- if (num_matches > 0) {
- return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
- }
- return CompilerType();
-}
-
-GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope,
- llvm::StringRef expr, llvm::StringRef prefix,
- lldb::LanguageType language,
- ResultType desired_type,
- const EvaluateExpressionOptions &options)
- : UserExpression(exe_scope, expr, prefix, language, desired_type, options) {
-}
-
-bool GoUserExpression::Parse(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory,
- bool generate_debug_info) {
- InstallContext(exe_ctx);
- m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText()));
- if (m_interpreter->Parse())
- return true;
- const char *error_cstr = m_interpreter->error().AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.Printf(eDiagnosticSeverityError,
- "expression can't be interpreted or run");
- return false;
-}
-
-lldb::ExpressionResults
-GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager,
- ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS |
- LIBLLDB_LOG_STEP));
-
- lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy();
- lldb::ExpressionResults execution_results = lldb::eExpressionSetupError;
-
- Process *process = exe_ctx.GetProcessPtr();
- Target *target = exe_ctx.GetTargetPtr();
-
- if (target == nullptr || process == nullptr ||
- process->GetState() != lldb::eStateStopped) {
- if (execution_policy == eExecutionPolicyAlways) {
- if (log)
- log->Printf("== [GoUserExpression::Evaluate] Expression may not run, "
- "but is not constant ==");
-
- diagnostic_manager.PutString(eDiagnosticSeverityError,
- "expression needed to run but couldn't");
-
- return execution_results;
- }
- }
-
- m_interpreter->set_use_dynamic(options.GetUseDynamic());
- ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx);
- Status err = m_interpreter->error();
- m_interpreter.reset();
-
- if (!result_val_sp) {
- const char *error_cstr = err.AsCString();
- if (error_cstr && error_cstr[0])
- diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr);
- else
- diagnostic_manager.PutString(eDiagnosticSeverityError,
- "expression can't be interpreted or run");
- return lldb::eExpressionDiscarded;
- }
- result.reset(new ExpressionVariable(ExpressionVariable::eKindGo));
- result->m_live_sp = result->m_frozen_sp = result_val_sp;
- result->m_flags |= ExpressionVariable::EVIsProgramReference;
- PersistentExpressionState *pv =
- target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo);
- if (pv != nullptr) {
- result->SetName(pv->GetNextPersistentVariableName(
- *target, pv->GetPersistentVariablePrefix()));
- pv->AddVariable(result);
- }
- return lldb::eExpressionCompleted;
-}
-
-bool GoUserExpression::GoInterpreter::Parse() {
- for (std::unique_ptr<GoASTStmt> stmt(m_parser.Statement()); stmt;
- stmt.reset(m_parser.Statement())) {
- if (m_parser.Failed())
- break;
- m_statements.emplace_back(std::move(stmt));
- }
- if (m_parser.Failed() || !m_parser.AtEOF())
- m_parser.GetError(m_error);
-
- return m_error.Success();
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx) {
- m_exe_ctx = exe_ctx;
- ValueObjectSP result;
- for (const std::unique_ptr<GoASTStmt> &stmt : m_statements) {
- result = EvaluateStatement(stmt.get());
- if (m_error.Fail())
- return nullptr;
- }
- return result;
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::EvaluateStatement(
- const lldb_private::GoASTStmt *stmt) {
- ValueObjectSP result;
- switch (stmt->GetKind()) {
- case GoASTNode::eBlockStmt: {
- const GoASTBlockStmt *block = llvm::cast<GoASTBlockStmt>(stmt);
- for (size_t i = 0; i < block->NumList(); ++i)
- result = EvaluateStatement(block->GetList(i));
- break;
- }
- case GoASTNode::eBadStmt:
- m_parser.GetError(m_error);
- break;
- case GoASTNode::eExprStmt: {
- const GoASTExprStmt *expr = llvm::cast<GoASTExprStmt>(stmt);
- return EvaluateExpr(expr->GetX());
- }
- default:
- m_error.SetErrorStringWithFormat("%s node not supported",
- stmt->GetKindName());
- }
- return result;
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::EvaluateExpr(
- const lldb_private::GoASTExpr *e) {
- if (e)
- return e->Visit<ValueObjectSP>(this);
- return ValueObjectSP();
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitParenExpr(
- const lldb_private::GoASTParenExpr *e) {
- return EvaluateExpr(e->GetX());
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) {
- ValueObjectSP val;
- if (m_frame) {
- VariableSP var_sp;
- std::string varname = e->GetName().m_value.str();
- if (varname.size() > 1 && varname[0] == '$') {
- RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
- const RegisterInfo *reg =
- reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
- if (reg) {
- std::string type;
- switch (reg->encoding) {
- case lldb::eEncodingSint:
- type.append("int");
- break;
- case lldb::eEncodingUint:
- type.append("uint");
- break;
- case lldb::eEncodingIEEE754:
- type.append("float");
- break;
- default:
- m_error.SetErrorString("Invalid register encoding");
- return nullptr;
- }
- switch (reg->byte_size) {
- case 8:
- type.append("64");
- break;
- case 4:
- type.append("32");
- break;
- case 2:
- type.append("16");
- break;
- case 1:
- type.append("8");
- break;
- default:
- m_error.SetErrorString("Invalid register size");
- return nullptr;
- }
- ValueObjectSP regVal = ValueObjectRegister::Create(
- m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
- CompilerType goType =
- LookupType(m_frame->CalculateTarget(), ConstString(type));
- if (regVal) {
- regVal = regVal->Cast(goType);
- return regVal;
- }
- }
- m_error.SetErrorString("Invalid register name");
- return nullptr;
- }
- VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
- if (var_list_sp) {
- var_sp = var_list_sp->FindVariable(ConstString(varname));
- if (var_sp)
- val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
- else {
- // When a variable is on the heap instead of the stack, go records a
- // variable '&x' instead of 'x'.
- var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
- if (var_sp) {
- val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
- if (val)
- val = val->Dereference(m_error);
- if (m_error.Fail())
- return nullptr;
- }
- }
- }
- if (!val) {
- m_error.Clear();
- TargetSP target = m_frame->CalculateTarget();
- if (!target) {
- m_error.SetErrorString("No target");
- return nullptr;
- }
- var_sp =
- FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
- if (var_sp)
- return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
- }
- }
- if (!val)
- m_error.SetErrorStringWithFormat("Unknown variable %s",
- e->GetName().m_value.str().c_str());
- return val;
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) {
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (!target)
- return nullptr;
- return target->Dereference(m_error);
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitSelectorExpr(
- const lldb_private::GoASTSelectorExpr *e) {
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (target) {
- if (target->GetCompilerType().IsPointerType()) {
- target = target->Dereference(m_error);
- if (m_error.Fail())
- return nullptr;
- }
- ConstString field(e->GetSel()->GetName().m_value);
- ValueObjectSP result = target->GetChildMemberWithName(field, true);
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString());
- return result;
- }
- if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX())) {
- if (VariableSP global = FindGlobalVariable(
- m_exe_ctx.GetTargetSP(), package->GetName().m_value + "." +
- e->GetSel()->GetName().m_value)) {
- if (m_frame) {
- m_error.Clear();
- return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic);
- }
- }
- }
- if (const GoASTBasicLit *packageLit =
- llvm::dyn_cast<GoASTBasicLit>(e->GetX())) {
- if (packageLit->GetValue().m_type == GoLexer::LIT_STRING) {
- std::string value = packageLit->GetValue().m_value.str();
- value = value.substr(1, value.size() - 2);
- if (VariableSP global = FindGlobalVariable(
- m_exe_ctx.GetTargetSP(),
- value + "." + e->GetSel()->GetName().m_value)) {
- if (m_frame) {
- m_error.Clear();
- return m_frame->TrackGlobalVariable(global, m_use_dynamic);
- }
- }
- }
- }
- // EvaluateExpr should have already set m_error.
- return target;
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitBasicLit(
- const lldb_private::GoASTBasicLit *e) {
- std::string value = e->GetValue().m_value.str();
- if (e->GetValue().m_type != GoLexer::LIT_INTEGER) {
- m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str());
- return nullptr;
- }
- errno = 0;
- int64_t intvalue = strtol(value.c_str(), nullptr, 0);
- if (errno != 0) {
- m_error.SetErrorToErrno();
- return nullptr;
- }
- DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0));
- TargetSP target = m_exe_ctx.GetTargetSP();
- if (!target) {
- m_error.SetErrorString("No target");
- return nullptr;
- }
- ByteOrder order = target->GetArchitecture().GetByteOrder();
- uint8_t addr_size = target->GetArchitecture().GetAddressByteSize();
- DataEncoder enc(buf, order, addr_size);
- enc.PutU64(0, static_cast<uint64_t>(intvalue));
- DataExtractor data(buf, order, addr_size);
-
- CompilerType type = LookupType(target, ConstString("int64"));
- return ValueObject::CreateValueObjectFromData(llvm::StringRef(), data,
- m_exe_ctx, type);
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitIndexExpr(
- const lldb_private::GoASTIndexExpr *e) {
- ValueObjectSP target = EvaluateExpr(e->GetX());
- if (!target)
- return nullptr;
- ValueObjectSP index = EvaluateExpr(e->GetIndex());
- if (!index)
- return nullptr;
- bool is_signed;
- if (!index->GetCompilerType().IsIntegerType(is_signed)) {
- m_error.SetErrorString("Unsupported index");
- return nullptr;
- }
- size_t idx;
- if (is_signed)
- idx = index->GetValueAsSigned(0);
- else
- idx = index->GetValueAsUnsigned(0);
- if (GoASTContext::IsGoSlice(target->GetCompilerType())) {
- target = target->GetStaticValue();
- ValueObjectSP cap =
- target->GetChildMemberWithName(ConstString("cap"), true);
- if (cap) {
- uint64_t capval = cap->GetValueAsUnsigned(0);
- if (idx >= capval) {
- m_error.SetErrorStringWithFormat("Invalid index %" PRIu64
- " , cap = %" PRIu64,
- uint64_t(idx), capval);
- return nullptr;
- }
- }
- target = target->GetChildMemberWithName(ConstString("array"), true);
- if (target && m_use_dynamic != eNoDynamicValues) {
- ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic);
- if (dynamic)
- target = dynamic;
- }
- if (!target)
- return nullptr;
- return target->GetSyntheticArrayMember(idx, true);
- }
- return target->GetChildAtIndex(idx, true);
-}
-
-ValueObjectSP
-GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e) {
- ValueObjectSP x = EvaluateExpr(e->GetX());
- if (!x)
- return nullptr;
- switch (e->GetOp()) {
- case GoLexer::OP_AMP: {
- CompilerType type = x->GetCompilerType().GetPointerType();
- uint64_t address = x->GetAddressOf();
- return ValueObject::CreateValueObjectFromAddress(llvm::StringRef(), address,
- m_exe_ctx, type);
- }
- case GoLexer::OP_PLUS:
- return x;
- default:
- m_error.SetErrorStringWithFormat(
- "Operator %s not supported",
- GoLexer::LookupToken(e->GetOp()).str().c_str());
- return nullptr;
- }
-}
-
-CompilerType GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e) {
- TargetSP target = m_exe_ctx.GetTargetSP();
- if (auto *id = llvm::dyn_cast<GoASTIdent>(e)) {
- CompilerType result =
- LookupType(target, ConstString(id->GetName().m_value));
- if (result.IsValid())
- return result;
- std::string fullname = (m_package + "." + id->GetName().m_value).str();
- result = LookupType(target, ConstString(fullname));
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
- return result;
- }
- if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e)) {
- std::string package;
- if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX())) {
- package = pkg_node->GetName().m_value.str();
- } else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX())) {
- if (str_node->GetValue().m_type == GoLexer::LIT_STRING) {
- package = str_node->GetValue().m_value.substr(1).str();
- package.resize(package.length() - 1);
- }
- }
- if (package.empty()) {
- m_error.SetErrorStringWithFormat("Invalid %s in type expression",
- sel->GetX()->GetKindName());
- return CompilerType();
- }
- std::string fullname =
- (package + "." + sel->GetSel()->GetName().m_value).str();
- CompilerType result = LookupType(target, ConstString(fullname));
- if (!result)
- m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
- return result;
- }
- if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e)) {
- CompilerType elem = EvaluateType(star->GetX());
- return elem.GetPointerType();
- }
- if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
- return EvaluateType(paren->GetX());
- if (auto *array = llvm::dyn_cast<GoASTArrayType>(e)) {
- CompilerType elem = EvaluateType(array->GetElt());
- }
-
- m_error.SetErrorStringWithFormat("Invalid %s in type expression",
- e->GetKindName());
- return CompilerType();
-}
-
-ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
- const lldb_private::GoASTCallExpr *e) {
- ValueObjectSP x = EvaluateExpr(e->GetFun());
- if (x || e->NumArgs() != 1) {
- m_error.SetErrorStringWithFormat("Code execution not supported");
- return nullptr;
- }
- m_error.Clear();
- CompilerType type = EvaluateType(e->GetFun());
- if (!type) {
- return nullptr;
- }
- ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
- if (!value)
- return nullptr;
- // TODO: Handle special conversions
- return value->Cast(type);
-}
-
-GoPersistentExpressionState::GoPersistentExpressionState()
- : PersistentExpressionState(eKindGo) {}
-
-void GoPersistentExpressionState::RemovePersistentVariable(
- lldb::ExpressionVariableSP variable) {
- RemoveVariable(variable);
-
- const char *name = variable->GetName().AsCString();
-
- if (*(name++) != '$')
- return;
- if (*(name++) != 'g')
- return;
- if (*(name++) != 'o')
- return;
-
- if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1)
- m_next_persistent_variable_id--;
-}
diff --git a/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/source/Plugins/ExpressionParser/Go/GoUserExpression.h
deleted file mode 100644
index e2839da9bfdd..000000000000
--- a/source/Plugins/ExpressionParser/Go/GoUserExpression.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//===-- GoUserExpression.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_GoUserExpression_h_
-#define liblldb_GoUserExpression_h_
-
-// C Includes
-// C++ Includes
-#include <memory>
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Expression/ExpressionVariable.h"
-#include "lldb/Expression/UserExpression.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-class GoParser;
-
-class GoPersistentExpressionState : public PersistentExpressionState {
-public:
- GoPersistentExpressionState();
-
- llvm::StringRef
- GetPersistentVariablePrefix(bool is_error) const override {
- return "$go";
- }
- void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override;
-
- lldb::addr_t LookupSymbol(const ConstString &name) override {
- return LLDB_INVALID_ADDRESS;
- }
-
- static bool classof(const PersistentExpressionState *pv) {
- return pv->getKind() == PersistentExpressionState::eKindGo;
- }
-
-private:
- uint32_t m_next_persistent_variable_id; ///< The counter used by
- ///GetNextResultName().
-};
-
-//----------------------------------------------------------------------
-/// @class GoUserExpression GoUserExpression.h
-/// "lldb/Expression/GoUserExpression.h" Encapsulates a single expression for
-/// use with Go
-///
-/// LLDB uses expressions for various purposes, notably to call functions
-/// and as a backend for the expr command. GoUserExpression encapsulates the
-/// objects needed to parse and interpret an expression.
-//----------------------------------------------------------------------
-class GoUserExpression : public UserExpression {
-public:
- GoUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr,
- llvm::StringRef prefix, lldb::LanguageType language,
- ResultType desired_type,
- const EvaluateExpressionOptions &options);
-
- bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb_private::ExecutionPolicy execution_policy,
- bool keep_result_in_memory, bool generate_debug_info) override;
-
- bool CanInterpret() override { return true; }
- bool FinalizeJITExecution(
- DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- lldb::ExpressionVariableSP &result,
- lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
- lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override {
- return true;
- }
-
-protected:
- lldb::ExpressionResults
- DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx,
- const EvaluateExpressionOptions &options,
- lldb::UserExpressionSP &shared_ptr_to_me,
- lldb::ExpressionVariableSP &result) override;
-
-private:
- class GoInterpreter;
- std::unique_ptr<GoInterpreter> m_interpreter;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_GoUserExpression_h_
diff --git a/source/Plugins/ExpressionParser/Go/gen_go_ast.py b/source/Plugins/ExpressionParser/Go/gen_go_ast.py
deleted file mode 100644
index 3be0e5f506ee..000000000000
--- a/source/Plugins/ExpressionParser/Go/gen_go_ast.py
+++ /dev/null
@@ -1,464 +0,0 @@
-import StringIO
-
-
-def addNodes():
- addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
- addNode(
- "AssignStmt",
- "Stmt",
- "lhs",
- "[]Expr",
- "rhs",
- "[]Expr",
- "define",
- "bool")
- addNode("BadDecl", "Decl")
- addNode("BadExpr", "Expr")
- addNode("BadStmt", "Stmt")
- addNode("BasicLit", "Expr", "value", "Token")
- addNode("BinaryExpr", "Expr", "x", "Expr", "y", "Expr", "op", "TokenType")
- addNode("BlockStmt", "Stmt", "list", "[]Stmt")
- addNode("Ident", "Expr", "name", "Token")
- addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
- addNode(
- "CallExpr",
- "Expr",
- "fun",
- "Expr",
- "args",
- "[]Expr",
- "ellipsis",
- "bool")
- addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
- addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
- addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
- addNode("CompositeLit", "Expr", "type", "Expr", "elts", "[]Expr")
- addNode("DeclStmt", "Stmt", "decl", "Decl")
- addNode("DeferStmt", "Stmt", "call", "CallExpr")
- addNode("Ellipsis", "Expr", "elt", "Expr")
- addNode("EmptyStmt", "Stmt")
- addNode("ExprStmt", "Stmt", "x", "Expr")
- addNode(
- "Field",
- "Node",
- "names",
- "[]Ident",
- "type",
- "Expr",
- "tag",
- "BasicLit")
- addNode("FieldList", "Node", "list", "[]Field")
- addNode(
- "ForStmt",
- "Stmt",
- "init",
- "Stmt",
- "cond",
- "Expr",
- "post",
- "Stmt",
- "body",
- "BlockStmt")
- addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
- addNode(
- "FuncDecl",
- "Decl",
- "recv",
- "FieldList",
- "name",
- "Ident",
- "type",
- "FuncType",
- "body",
- "BlockStmt")
- addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
- addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
- addNode("GoStmt", "Stmt", "call", "CallExpr")
- addNode(
- "IfStmt",
- "Stmt",
- "init",
- "Stmt",
- "cond",
- "Expr",
- "body",
- "BlockStmt",
- "els",
- "Stmt")
- addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
- addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
- addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
- addNode("InterfaceType", "Expr", "methods", "FieldList")
- addNode("KeyValueExpr", "Expr", "key", "Expr", "value", "Expr")
- addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
- addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
- addNode("ParenExpr", "Expr", "x", "Expr")
- addNode(
- "RangeStmt",
- "Stmt",
- "key",
- "Expr",
- "value",
- "Expr",
- "define",
- "bool",
- "x",
- "Expr",
- "body",
- "BlockStmt")
- addNode("ReturnStmt", "Stmt", "results", "[]Expr")
- addNode("SelectStmt", "Stmt", "body", "BlockStmt")
- addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
- addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
- addNode(
- "SliceExpr",
- "Expr",
- "x",
- "Expr",
- "low",
- "Expr",
- "high",
- "Expr",
- "max",
- "Expr",
- "slice3",
- "bool")
- addNode("StarExpr", "Expr", "x", "Expr")
- addNode("StructType", "Expr", "fields", "FieldList")
- addNode(
- "SwitchStmt",
- "Stmt",
- "init",
- "Stmt",
- "tag",
- "Expr",
- "body",
- "BlockStmt")
- addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
- addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
- addNode(
- "TypeSwitchStmt",
- "Stmt",
- "init",
- "Stmt",
- "assign",
- "Stmt",
- "body",
- "BlockStmt")
- addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
- addNode(
- "ValueSpec",
- "Spec",
- "names",
- "[]Ident",
- "type",
- "Expr",
- "values",
- "[]Expr")
- addParent("Decl", "Node")
- addParent("Expr", "Node")
- addParent("Spec", "Node")
- addParent("Stmt", "Node")
-
-
-class Member(object):
-
- def __init__(self, name, typename):
- self.title = name.title()
- self.sname = name
- self.mname = 'm_' + name
- self.is_list = typename.startswith("[]")
- self.is_value = isValueType(typename)
- if self.is_value:
- self.argtype = typename
- self.mtype = typename
- elif self.is_list:
- self.argtype = 'GoAST' + typename[2:]
- self.mtype = 'std::vector<std::unique_ptr<%s> >' % self.argtype
- else:
- self.argtype = 'GoAST' + typename
- self.mtype = 'std::unique_ptr<%s>' % self.argtype
- self.mname = self.mname + '_up'
-
-
-kinds = {}
-parentClasses = StringIO.StringIO()
-childClasses = StringIO.StringIO()
-walker = StringIO.StringIO()
-
-
-def startClass(name, parent, out):
- out.write("""
-class GoAST%s : public GoAST%s
-{
- public:
-""" % (name, parent))
-
-
-def endClass(name, out):
- out.write("""
- %(name)s(const %(name)s &) = delete;
- const %(name)s &operator=(const %(name)s &) = delete;
-};
-""" % {'name': 'GoAST' + name})
-
-
-def addNode(name, parent, *children):
- startClass(name, parent, childClasses)
- l = kinds.setdefault(parent, [])
- l.append(name)
- children = createMembers(name, children)
- addConstructor(name, parent, children)
- childClasses.write("""
- const char *
- GetKindName() const override
- {
- return "%(name)s";
- }
-
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() == e%(name)s;
- }
- """ % {'name': name})
- addChildren(name, children)
- endClass(name, childClasses)
-
-
-def isValueType(typename):
- if typename[0].islower():
- return True
- if typename[0].isupper():
- return typename.startswith('Token') or typename == 'ChanDir'
- return False
-
-
-def createMembers(name, children):
- l = len(children)
- if (l % 2) != 0:
- raise Exception("Invalid children for %s: %s" % (name, children))
- return [Member(children[i], children[i + 1]) for i in xrange(0, l, 2)]
-
-
-def addConstructor(name, parent, children):
- for c in children:
- if c.is_list:
- children = [x for x in children if x.is_value]
- break
- childClasses.write(' ')
- if len(children) == 1:
- childClasses.write('explicit ')
- childClasses.write('GoAST%s(' % name)
- for i in xrange(len(children)):
- if i > 0:
- childClasses.write(', ')
-
- c = children[i]
- if c.is_value:
- childClasses.write(c.argtype)
- childClasses.write(' ')
- else:
- childClasses.write('%s *' % c.argtype)
- childClasses.write(c.sname)
- childClasses.write(') : GoAST%s(e%s)' % (parent, name))
- for c in children:
- childClasses.write(', ')
- childClasses.write('%(mname)s(%(sname)s)' % c.__dict__)
- childClasses.write(""" {}
- ~GoAST%s() override = default;
-""" % name)
-
-
-def addChildren(name, children):
- if len(children) == 0:
- return
- walker.write("""
- case e%(n)s:
- {
- GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
- (void)n;""" % {'n': name})
- for c in children:
- if c.is_list:
- childClasses.write("""
- size_t
- Num%(title)s() const
- {
- return %(mname)s.size();
- }
- const %(argtype)s *
- Get%(title)s(int i) const
- {
- return %(mname)s[i].get();
- }
- void
- Add%(title)s(%(argtype)s *%(sname)s)
- {
- %(mname)s.push_back(std::unique_ptr<%(argtype)s>(%(sname)s));
- }
-""" % c.__dict__)
- walker.write("""
- for (auto& e : n->%s) { v(e.get()); }""" % c.mname)
- else:
- const = ''
- get = ''
- set = ''
- t = c.argtype
- if isValueType(t):
- set = '%(mname)s = %(sname)s' % c.__dict__
- t = t + ' '
- else:
- t = t + ' *'
- const = 'const '
- get = '.get()'
- set = '%(mname)s.reset(%(sname)s)' % c.__dict__
- walker.write("""
- v(n->%s.get());""" % c.mname)
- childClasses.write("""
- %(const)s%(type)s
- Get%(title)s() const
- {
- return %(mname)s%(get)s;
- }
- void
- Set%(title)s(%(type)s%(sname)s)
- {
- %(set)s;
- }
-""" % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
- childClasses.write('\n private:\n friend class GoASTNode;\n')
- walker.write("""
- return;
- }""")
- for c in children:
- childClasses.write(' %s %s;\n' % (c.mtype, c.mname))
-
-
-def addParent(name, parent):
- startClass(name, parent, parentClasses)
- l = kinds[name]
- minName = l[0]
- maxName = l[-1]
- parentClasses.write(""" template <typename R, typename V> R Visit(V *v) const;
-
- static bool
- classof(const GoASTNode *n)
- {
- return n->GetKind() >= e%s && n->GetKind() <= e%s;
- }
-
- protected:
- explicit GoAST%s(NodeKind kind) : GoASTNode(kind) { }
- private:
-""" % (minName, maxName, name))
- endClass(name, parentClasses)
-
-addNodes()
-
-print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// DO NOT EDIT.
-// Generated by gen_go_ast.py
-
-#ifndef liblldb_GoAST_h
-#define liblldb_GoAST_h
-
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "llvm/Support/Casting.h"
-#include "Plugins/ExpressionParser/Go/GoLexer.h"
-
-namespace lldb_private
-{
-
-class GoASTNode
-{
- public:
- typedef GoLexer::TokenType TokenType;
- typedef GoLexer::Token Token;
- enum ChanDir
- {
- eChanBidir,
- eChanSend,
- eChanRecv,
- };
- enum NodeKind
- {"""
-for l in kinds.itervalues():
- for x in l:
- print " e%s," % x
-print """ };
-
- virtual ~GoASTNode() = default;
-
- NodeKind
- GetKind() const
- {
- return m_kind;
- }
-
- virtual const char *GetKindName() const = 0;
-
- template <typename V> void WalkChildren(V &v);
-
- protected:
- explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
-
- private:
- const NodeKind m_kind;
-
- GoASTNode(const GoASTNode &) = delete;
- const GoASTNode &operator=(const GoASTNode &) = delete;
-};
-"""
-
-
-print parentClasses.getvalue()
-print childClasses.getvalue()
-
-for k, l in kinds.iteritems():
- if k == 'Node':
- continue
- print """
-template <typename R, typename V>
-R GoAST%s::Visit(V* v) const
-{
- switch(GetKind())
- {""" % k
- for subtype in l:
- print """ case e%(n)s:
- return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
-
- print """ default:
- assert(false && "Invalid kind");
- }
-}"""
-
-print """
-template <typename V>
-void GoASTNode::WalkChildren(V &v)
-{
- switch (m_kind)
- {
-"""
-print walker.getvalue()
-print"""
- case eEmptyStmt:
- case eBadDecl:
- case eBadExpr:
- case eBadStmt:
- break;
- }
-}
-
-} // namespace lldb_private
-
-#endif
-"""
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index 86744520ad63..85bc4a61c9d4 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -26,8 +26,7 @@
#include "Utility/ARM_DWARF_Registers.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
- // and countTrailingZeros function
+#include "llvm/Support/MathExtras.h"
using namespace lldb;
using namespace lldb_private;
@@ -777,10 +776,7 @@ bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) {
uint32_t random_data = rand();
const uint32_t addr_byte_size = GetAddressByteSize();
- if (!MemAWrite(context, address, random_data, addr_byte_size))
- return false;
-
- return true;
+ return MemAWrite(context, address, random_data, addr_byte_size);
}
// Write "bits (32) UNKNOWN" to register n. Helper function for many ARM
@@ -850,6 +846,7 @@ uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const {
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
is_apple = true;
break;
default:
@@ -3340,10 +3337,7 @@ bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteFlags(context, res.result, res.carry_out, res.overflow);
}
// Compare Negative (register) adds a register value and an optionally-shifted
@@ -3410,10 +3404,7 @@ bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteFlags(context, res.result, res.carry_out, res.overflow);
}
// Compare (immediate) subtracts an immediate value from a register value. It
@@ -3463,10 +3454,7 @@ bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteFlags(context, res.result, res.carry_out, res.overflow);
}
// Compare (register) subtracts an optionally-shifted register value from a
@@ -3542,10 +3530,7 @@ bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteFlags(context, res.result, res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteFlags(context, res.result, res.carry_out, res.overflow);
}
// Arithmetic Shift Right (immediate) shifts a register value right by an
@@ -9245,11 +9230,8 @@ bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode,
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// Reverse Subtract (register) subtracts a register value from an optionally-
@@ -9326,11 +9308,8 @@ bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// Reverse Subtract with Carry (immediate) subtracts a register value and the
@@ -9388,11 +9367,8 @@ bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode,
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// Reverse Subtract with Carry (register) subtracts a register value and the
@@ -9460,11 +9436,8 @@ bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// Subtract with Carry (immediate) subtracts an immediate value and the value
@@ -9531,11 +9504,8 @@ bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode,
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// Subtract with Carry (register) subtracts an optionally-shifted register
@@ -9620,11 +9590,8 @@ bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode,
EmulateInstruction::Context context;
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// This instruction subtracts an immediate value from a register value, and
@@ -9713,11 +9680,8 @@ bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode,
context.type = EmulateInstruction::eContextImmediate;
context.SetNoArgs();
- if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
- res.carry_out, res.overflow))
- return false;
-
- return true;
+ return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags,
+ res.carry_out, res.overflow);
}
// This instruction subtracts an immediate value from a register value, and
@@ -14153,11 +14117,8 @@ bool EmulateInstructionARM::BranchWritePC(const Context &context,
else
target = addr & 0xfffffffe;
- if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC, target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target);
}
// As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by
@@ -14191,11 +14152,8 @@ bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) {
LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr))
return false;
}
- if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC, target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, target);
}
// Dispatches to either BXWritePC or BranchWritePC based on architecture
@@ -14408,14 +14366,14 @@ bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) {
evaluate_options & eEmulateInstructionOptionIgnoreConditions;
bool success = false;
- if (m_opcode_cpsr == 0 || m_ignore_conditions == false) {
+ if (m_opcode_cpsr == 0 || !m_ignore_conditions) {
m_opcode_cpsr =
ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success);
}
// Only return false if we are unable to read the CPSR if we care about
// conditions
- if (success == false && m_ignore_conditions == false)
+ if (!success && !m_ignore_conditions)
return false;
uint32_t orig_pc_value = 0;
diff --git a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
index d1032f56f31c..d770b3bdc52e 100644
--- a/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulationStateARM.cpp
@@ -9,12 +9,12 @@
#include "EmulationStateARM.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "Utility/ARM_DWARF_Registers.h"
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
index 2f484ab5ea97..661a651c56c2 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
@@ -13,10 +13,10 @@
#include "lldb/Core/Address.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/RegisterValue.h"
#include "lldb/Utility/Stream.h"
#include "Plugins/Process/Utility/ARMDefines.h"
@@ -41,8 +41,7 @@
#include "Plugins/Process/Utility/RegisterInfos_arm64.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/MathExtras.h" // for SignExtend32 template function
- // and CountTrailingZeros_32 function
+#include "llvm/Support/MathExtras.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
@@ -437,7 +436,7 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) {
// Only return false if we are unable to read the CPSR if we care about
// conditions
- if (success == false && m_ignore_conditions == false)
+ if (!success && !m_ignore_conditions)
return false;
uint32_t orig_pc_value = 0;
@@ -547,11 +546,8 @@ bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N,
} else
return false;
- if (!WriteRegisterUnsigned(context, eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC, addr))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, addr);
}
bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) {
@@ -1097,9 +1093,7 @@ bool EmulateInstructionARM64::EmulateB(const uint32_t opcode) {
return false;
}
- if (!BranchTo(context, 64, target))
- return false;
- return true;
+ return BranchTo(context, 64, target);
}
bool EmulateInstructionARM64::EmulateBcond(const uint32_t opcode) {
diff --git a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
index 253bb935bca7..1d1bd74d3f61 100644
--- a/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
+++ b/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
@@ -10,10 +10,6 @@
#ifndef EmulateInstructionARM64_h_
#define EmulateInstructionARM64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
diff --git a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
index b65747e12890..7fccb2311026 100644
--- a/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
+++ b/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
@@ -14,12 +14,12 @@
#include "lldb/Core/Address.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/RegisterValue.h"
#include "lldb/Utility/Stream.h"
#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -35,7 +35,7 @@
#include "llvm/ADT/STLExtras.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
-#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64
+#include "Plugins/Process/Utility/RegisterContext_mips.h"
using namespace lldb;
using namespace lldb_private;
@@ -220,10 +220,8 @@ EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch,
}
bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) {
- if (arch.GetTriple().getArch() == llvm::Triple::mips ||
- arch.GetTriple().getArch() == llvm::Triple::mipsel)
- return true;
- return false;
+ return arch.GetTriple().getArch() == llvm::Triple::mips ||
+ arch.GetTriple().getArch() == llvm::Triple::mipsel;
}
const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num,
@@ -1350,10 +1348,7 @@ bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) {
context.type = eContextPopRegisterOffStack;
context.SetAddress(address);
- if (!WriteRegister(context, &reg_info_src, data_src))
- return false;
-
- return true;
+ return WriteRegister(context, &reg_info_src, data_src);
}
return false;
@@ -1450,11 +1445,8 @@ bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) {
context.SetImmediateSigned(imm);
context.type = eContextImmediate;
- if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt,
- imm))
- return true;
-
- return false;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips + rt, imm);
}
bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) {
@@ -1697,10 +1689,7 @@ bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) {
context.type = eContextPopRegisterOffStack;
context.SetAddress(base_address);
- if (!WriteRegister(context, &reg_info_src, data_src))
- return false;
-
- return true;
+ return WriteRegister(context, &reg_info_src, data_src);
}
return false;
@@ -1807,11 +1796,8 @@ bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) {
context.type = eContextAdjustStackPointer;
// update SP
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
- result))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips,
+ result);
}
static int IsAdd64bitOverflow(int32_t a, int32_t b) {
@@ -1864,11 +1850,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
/*
@@ -1947,11 +1930,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
/*
@@ -2122,11 +2102,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
/*
@@ -2189,11 +2166,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
@@ -2214,11 +2188,8 @@ bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
/*
@@ -2529,11 +2500,8 @@ bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
@@ -2556,10 +2524,7 @@ bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc);
}
bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) {
@@ -2688,11 +2653,8 @@ bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
@@ -2713,11 +2675,8 @@ bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- rs_val))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ rs_val);
}
/*
@@ -2758,11 +2717,8 @@ bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) {
}
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
@@ -2797,11 +2753,8 @@ bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
@@ -2836,11 +2789,8 @@ bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
/*
@@ -2898,11 +2848,8 @@ bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) {
}
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) {
@@ -2993,11 +2940,8 @@ bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
Context context;
context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) {
@@ -3039,11 +2983,8 @@ bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn,
Context context;
context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips,
+ target);
}
bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) {
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 5af12ad141aa..9d178dd97ddf 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -14,12 +14,12 @@
#include "lldb/Core/Address.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/RegisterValue.h"
#include "lldb/Utility/Stream.h"
#include "llvm-c/Disassembler.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -207,10 +207,8 @@ EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch,
}
bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) {
- if (arch.GetTriple().getArch() == llvm::Triple::mips64 ||
- arch.GetTriple().getArch() == llvm::Triple::mips64el)
- return true;
- return false;
+ return arch.GetTriple().getArch() == llvm::Triple::mips64 ||
+ arch.GetTriple().getArch() == llvm::Triple::mips64el;
}
const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num,
@@ -1099,13 +1097,24 @@ bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) {
Context context;
/* read <src> register */
- const int64_t src_opd_val = ReadRegisterUnsigned(
+ const uint64_t src_opd_val = ReadRegisterUnsigned(
eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success);
if (!success)
return false;
/* Check if this is daddiu sp, sp, imm16 */
if (dst == dwarf_sp_mips64) {
+ /*
+ * From the MIPS IV spec:
+ *
+ * The term “unsigned” in the instruction name is a misnomer; this
+ * operation is 64-bit modulo arithmetic that does not trap on overflow.
+ * It is appropriate for arithmetic which is not signed, such as address
+ * arithmetic, or integer arithmetic environments that ignore overflow,
+ * such as “C” language arithmetic.
+ *
+ * Assume 2's complement and rely on unsigned overflow here.
+ */
uint64_t result = src_opd_val + imm;
RegisterInfo reg_info_sp;
@@ -1229,10 +1238,7 @@ bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) {
Context context;
context.type = eContextRegisterLoad;
- if (!WriteRegister(context, &reg_info_src, data_src))
- return false;
-
- return true;
+ return WriteRegister(context, &reg_info_src, data_src);
}
return false;
@@ -1251,11 +1257,8 @@ bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) {
context.SetImmediateSigned(imm);
context.type = eContextImmediate;
- if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt,
- imm))
- return true;
-
- return false;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF,
+ dwarf_zero_mips64 + rt, imm);
}
bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) {
@@ -1383,11 +1386,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
/*
@@ -1622,11 +1622,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
@@ -1648,11 +1645,8 @@ bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
static int IsAdd64bitOverflow(int64_t a, int64_t b) {
@@ -1736,11 +1730,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
/*
@@ -1803,11 +1794,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) {
context.type = eContextRelativeBranchImmediate;
context.SetImmediate(current_inst_size + offset);
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
@@ -1830,10 +1818,8 @@ bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ pc);
}
bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) {
@@ -1962,11 +1948,8 @@ bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
@@ -1987,11 +1970,8 @@ bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- rs_val))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ rs_val);
}
/*
@@ -2041,11 +2021,8 @@ bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
@@ -2080,11 +2057,8 @@ bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
@@ -2119,11 +2093,8 @@ bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
/*
@@ -2182,11 +2153,8 @@ bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) {
Context context;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) {
@@ -2277,11 +2245,8 @@ bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn,
Context context;
context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) {
@@ -2323,11 +2288,8 @@ bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn,
Context context;
context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
- target))
- return false;
-
- return true;
+ return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64,
+ target);
}
bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) {
diff --git a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
index c2433d59830e..e9783633ac7d 100644
--- a/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
+++ b/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
@@ -10,10 +10,6 @@
#ifndef EmulateInstructionMIPS64_h_
#define EmulateInstructionMIPS64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
index be65de9a5063..e9a1da6dd394 100644
--- a/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
+++ b/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h
@@ -10,10 +10,6 @@
#ifndef EmulateInstructionPPC64_h_
#define EmulateInstructionPPC64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Log.h"
diff --git a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h
index e9af5a6cdc74..1439f86e586f 100644
--- a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h
+++ b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h
@@ -10,10 +10,6 @@
#ifndef liblldb_AddressSanitizerRuntime_h_
#define liblldb_AddressSanitizerRuntime_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h
index dc737d22a67a..e6482d394efa 100644
--- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h
+++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ThreadSanitizerRuntime_h_
#define liblldb_ThreadSanitizerRuntime_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/Target/InstrumentationRuntime.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index 7ef3aecdb89f..3040b8b39052 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include "llvm/Support/MathExtras.h"
@@ -59,10 +58,9 @@ template <typename ptr_t> struct jit_descriptor {
namespace {
-PropertyDefinition g_properties[] = {
+static constexpr PropertyDefinition g_properties[] = {
{"enable-jit-breakpoint", OptionValue::eTypeBoolean, true, true, nullptr,
- nullptr, "Enable breakpoint on __jit_debug_register_code."},
- {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+ {}, "Enable breakpoint on __jit_debug_register_code."}};
enum { ePropertyEnableJITBreakpoint };
@@ -316,7 +314,7 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
char jit_name[64];
snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr);
module_sp = m_process->ReadModuleFromMemory(
- FileSpec(jit_name, false), symbolfile_addr, symbolfile_size);
+ FileSpec(jit_name), symbolfile_addr, symbolfile_size);
if (module_sp && module_sp->GetObjectFile()) {
// load the symbol table right away
diff --git a/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
index 6269860825db..a22016601293 100644
--- a/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
+++ b/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
@@ -10,12 +10,8 @@
#ifndef liblldb_JITLoaderGDB_h_
#define liblldb_JITLoaderGDB_h_
-// C Includes
-// C++ Includes
#include <map>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/JITLoader.h"
#include "lldb/Target/Process.h"
diff --git a/source/Plugins/Language/CMakeLists.txt b/source/Plugins/Language/CMakeLists.txt
index 4b92a8ef866b..7869074566d1 100644
--- a/source/Plugins/Language/CMakeLists.txt
+++ b/source/Plugins/Language/CMakeLists.txt
@@ -1,6 +1,4 @@
+add_subdirectory(ClangCommon)
add_subdirectory(CPlusPlus)
-add_subdirectory(Go)
-add_subdirectory(Java)
add_subdirectory(ObjC)
add_subdirectory(ObjCPlusPlus)
-add_subdirectory(OCaml)
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 82b7ac1675fa..40200503a8a7 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "BlockPointer.h"
#include "lldb/Core/ValueObject.h"
@@ -89,7 +85,7 @@ public:
size_t CalculateNumChildren() override {
const bool omit_empty_base_classes = false;
- return m_block_struct_type.GetNumChildren(omit_empty_base_classes);
+ return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr);
}
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
diff --git a/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 180440a244a4..bc357aa52b84 100644
--- a/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -9,13 +9,16 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
LibCxxInitializerList.cpp
LibCxxList.cpp
LibCxxMap.cpp
+ LibCxxOptional.cpp
LibCxxQueue.cpp
LibCxxTuple.cpp
LibCxxUnorderedMap.cpp
+ LibCxxVariant.cpp
LibCxxVector.cpp
LibStdcpp.cpp
LibStdcppTuple.cpp
LibStdcppUniquePointer.cpp
+ MSVCUndecoratedNameParser.cpp
LINK_LIBS
lldbCore
@@ -24,6 +27,8 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
lldbSymbol
lldbTarget
lldbUtility
+ lldbPluginClangCommon
+
LINK_COMPONENTS
Support
)
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 2c63e6467d4c..982b286d0f05 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -9,20 +9,17 @@
#include "CPlusPlusLanguage.h"
-// C Includes
#include <cctype>
#include <cstring>
-// C++ Includes
#include <functional>
#include <memory>
#include <mutex>
#include <set>
-// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
+#include "llvm/Demangle/ItaniumDemangle.h"
-// Project includes
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/DataFormatters/CXXFunctionPointer.h"
@@ -30,7 +27,6 @@
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/VectorType.h"
#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/FastDemangle.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
@@ -39,7 +35,9 @@
#include "CxxStringTypes.h"
#include "LibCxx.h"
#include "LibCxxAtomic.h"
+#include "LibCxxVariant.h"
#include "LibStdcpp.h"
+#include "MSVCUndecoratedNameParser.h"
using namespace lldb;
using namespace lldb_private;
@@ -143,10 +141,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) {
}
// We processed all characters. It is a vaild basename.
- if (idx == basename.size())
- return true;
-
- return false;
+ return idx == basename.size();
}
bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
@@ -251,19 +246,23 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
// FIXME!! we should really run through all the known C++ Language plugins
// and ask each one if this is a C++ mangled name
-
+
if (name == nullptr)
return false;
-
- // MSVC style mangling
+
+ // MSVC style mangling
if (name[0] == '?')
return true;
-
+
return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
}
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
+ if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
+ return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
+ identifier);
+
CPlusPlusNameParser parser(name);
if (auto full_name = parser.ParseAsFullName()) {
identifier = full_name.getValue().basename;
@@ -273,53 +272,89 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier(
return false;
}
-/// Given a mangled function `mangled`, replace all the primitive function type
-/// arguments of `search` with type `replace`.
-static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
- llvm::StringRef search,
- llvm::StringRef replace) {
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
-
- const size_t max_len =
- mangled.size() + mangled.count(search) * replace.size() + 1;
-
- // Make a temporary buffer to fix up the mangled parameter types and copy the
- // original there
- std::string output_buf;
- output_buf.reserve(max_len);
- output_buf.insert(0, mangled.str());
- ptrdiff_t replaced_offset = 0;
-
- auto swap_parms_hook = [&](const char *parsee) {
- if (!parsee || !*parsee)
- return;
-
- // Check whether we've found a substitutee
- llvm::StringRef s(parsee);
- if (s.startswith(search)) {
- // account for the case where a replacement is of a different length to
- // the original
- replaced_offset += replace.size() - search.size();
-
- ptrdiff_t replace_idx = (mangled.size() - s.size()) + replaced_offset;
- output_buf.erase(replace_idx, search.size());
- output_buf.insert(replace_idx, replace.str());
+namespace {
+class NodeAllocator {
+ llvm::BumpPtrAllocator Alloc;
+
+public:
+ void reset() { Alloc.Reset(); }
+
+ template <typename T, typename... Args> T *makeNode(Args &&... args) {
+ return new (Alloc.Allocate(sizeof(T), alignof(T)))
+ T(std::forward<Args>(args)...);
+ }
+
+ void *allocateNodeArray(size_t sz) {
+ return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz,
+ alignof(llvm::itanium_demangle::Node *));
+ }
+};
+
+/// Given a mangled function `Mangled`, replace all the primitive function type
+/// arguments of `Search` with type `Replace`.
+class TypeSubstitutor
+ : public llvm::itanium_demangle::AbstractManglingParser<TypeSubstitutor,
+ NodeAllocator> {
+ /// Input character until which we have constructed the respective output
+ /// already
+ const char *Written;
+
+ llvm::StringRef Search;
+ llvm::StringRef Replace;
+ llvm::SmallString<128> Result;
+
+ /// Whether we have performed any substitutions.
+ bool Substituted;
+
+ void reset(llvm::StringRef Mangled, llvm::StringRef Search,
+ llvm::StringRef Replace) {
+ AbstractManglingParser::reset(Mangled.begin(), Mangled.end());
+ Written = Mangled.begin();
+ this->Search = Search;
+ this->Replace = Replace;
+ Result.clear();
+ Substituted = false;
+ }
+
+ void appendUnchangedInput() {
+ Result += llvm::StringRef(Written, First - Written);
+ Written = First;
+ }
+
+public:
+ TypeSubstitutor() : AbstractManglingParser(nullptr, nullptr) {}
+
+ ConstString substitute(llvm::StringRef Mangled, llvm::StringRef From,
+ llvm::StringRef To) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ reset(Mangled, From, To);
+ if (parse() == nullptr) {
+ LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled);
+ return ConstString();
}
- };
+ if (!Substituted)
+ return ConstString();
- // FastDemangle will call our hook for each instance of a primitive type,
- // allowing us to perform substitution
- char *const demangled =
- FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook);
+ // Append any trailing unmodified input.
+ appendUnchangedInput();
+ LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result);
+ return ConstString(Result);
+ }
- if (log)
- log->Printf("substituted mangling for %s:{%s} %s:{%s}\n",
- mangled.str().c_str(), demangled, output_buf.c_str(),
- FastDemangle(output_buf.c_str()));
- // FastDemangle malloc'd this string.
- free(demangled);
+ llvm::itanium_demangle::Node *parseType() {
+ if (llvm::StringRef(First, numLeft()).startswith(Search)) {
+ // We found a match. Append unmodified input up to this point.
+ appendUnchangedInput();
- return output_buf == mangled ? ConstString() : ConstString(output_buf);
+ // And then perform the replacement.
+ Result += Replace;
+ Written += Search.size();
+ Substituted = true;
+ }
+ return AbstractManglingParser::parseType();
+ }
+};
}
uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
@@ -348,23 +383,24 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings(
alternates.insert(ConstString(fixed_scratch));
}
+ TypeSubstitutor TS;
// `char` is implementation defined as either `signed` or `unsigned`. As a
// result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed
// char, 'h'-unsigned char. If we're looking for symbols with a signed char
// parameter, try finding matches which have the general case 'c'.
if (ConstString char_fixup =
- SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "a", "c"))
+ TS.substitute(mangled_name.GetStringRef(), "a", "c"))
alternates.insert(char_fixup);
// long long parameter mangling 'x', may actually just be a long 'l' argument
if (ConstString long_fixup =
- SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "x", "l"))
+ TS.substitute(mangled_name.GetStringRef(), "x", "l"))
alternates.insert(long_fixup);
// unsigned long long parameter mangling 'y', may actually just be unsigned
// long 'm' argument
if (ConstString ulong_fixup =
- SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "y", "m"))
+ TS.substitute(mangled_name.GetStringRef(), "y", "m"))
alternates.insert(ulong_fixup);
return alternates.size() - start_size;
@@ -385,8 +421,17 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
#ifndef LLDB_DISABLE_PYTHON
lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(
- stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider,
+ stl_summary_flags,
+ lldb_private::formatters::LibcxxStringSummaryProviderASCII,
"std::string summary provider"));
+ lldb::TypeSummaryImplSP std_stringu16_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags,
+ lldb_private::formatters::LibcxxStringSummaryProviderUTF16,
+ "std::u16string summary provider"));
+ lldb::TypeSummaryImplSP std_stringu32_summary_sp(new CXXFunctionSummaryFormat(
+ stl_summary_flags,
+ lldb_private::formatters::LibcxxStringSummaryProviderUTF32,
+ "std::u32string summary provider"));
lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(
stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider,
"std::wstring summary provider"));
@@ -400,6 +445,16 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::__1::allocator<char> >"),
std_string_summary_sp);
cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString(
+ "std::__1::basic_string<char16_t, std::__1::char_traits<char16_t>, "
+ "std::__1::allocator<char16_t> >"),
+ std_stringu16_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString(
+ "std::__1::basic_string<char32_t, std::__1::char_traits<char32_t>, "
+ "std::__1::allocator<char32_t> >"),
+ std_stringu32_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
ConstString("std::__ndk1::basic_string<char, "
"std::__ndk1::char_traits<char>, "
"std::__ndk1::allocator<char> >"),
@@ -493,6 +548,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::tuple synthetic children",
ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags,
true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator,
+ "libc++ std::optional synthetic children",
+ ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
+ stl_synth_flags, true);
+ AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator,
+ "libc++ std::variant synthetic children",
+ ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
+ stl_synth_flags, true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator,
@@ -519,6 +582,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags,
true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider,
+ "libc++ std::function summary provider",
+ ConstString("^std::__(ndk)?1::function<.+>$"), stl_summary_flags, true);
+
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(false);
AddCXXSummary(cpp_category_sp,
@@ -584,6 +652,16 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider,
"libc++ std::atomic summary provider",
ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxOptionalSummaryProvider,
+ "libc++ std::optional summary provider",
+ ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"),
+ stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxVariantSummaryProvider,
+ "libc++ std::variant summary provider",
+ ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"),
+ stl_summary_flags, true);
stl_summary_flags.SetSkipPointers(true);
@@ -610,11 +688,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"std::map iterator synthetic children",
ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags,
true);
-
- AddCXXSynthetic(
- cpp_category_sp, lldb_private::formatters::LibcxxFunctionFrontEndCreator,
- "std::function synthetic value provider",
- ConstString("^std::__(ndk)?1::function<.+>$"), stl_synth_flags, true);
#endif
}
@@ -1002,3 +1075,16 @@ CPlusPlusLanguage::GetHardcodedSynthetics() {
return g_formatters;
}
+
+bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
+ const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c",
+ ".h", ".hh", ".hpp", ".hxx", ".h++"};
+ for (auto suffix : suffixes) {
+ if (file_path.endswith_lower(suffix))
+ return true;
+ }
+
+ // Check if we're in a STL path (where the files usually have no extension
+ // that we could check for.
+ return file_path.contains("/usr/include/c++/");
+}
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 7380ef321305..3c8ca96e81f6 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -10,15 +10,12 @@
#ifndef liblldb_CPlusPlusLanguage_h_
#define liblldb_CPlusPlusLanguage_h_
-// C Includes
-// C++ Includes
#include <set>
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
-// Project includes
+#include "Plugins/Language/ClangCommon/ClangHighlighter.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
@@ -26,6 +23,8 @@
namespace lldb_private {
class CPlusPlusLanguage : public Language {
+ ClangHighlighter m_highlighter;
+
public:
class MethodName {
public:
@@ -90,6 +89,10 @@ public:
HardcodedFormatters::HardcodedSyntheticFinder
GetHardcodedSynthetics() override;
+ bool IsSourceFile(llvm::StringRef file_path) const override;
+
+ const Highlighter *GetHighlighter() const override { return &m_highlighter; }
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
index fe1d46f32c17..d46a53a7a704 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h
@@ -10,16 +10,12 @@
#ifndef liblldb_CPlusPlusNameParser_h_
#define liblldb_CPlusPlusNameParser_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-// Project includes
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 0f6fb54e8384..24185b314466 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -100,8 +100,11 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
if (!wchar_compiler_type)
return false;
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
- nullptr); // Safe to pass NULL for exe_scope here
+ // Safe to pass nullptr for exe_scope here.
+ llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
+ if (!size)
+ return false;
+ const uint32_t wchar_size = *size;
StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(valobj_addr);
@@ -194,8 +197,11 @@ bool lldb_private::formatters::WCharSummaryProvider(
if (!wchar_compiler_type)
return false;
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
- nullptr); // Safe to pass NULL for exe_scope here
+ // Safe to pass nullptr for exe_scope here.
+ llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
+ if (!size)
+ return false;
+ const uint32_t wchar_size = *size;
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
options.SetData(data);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 95e02a473cd7..7e8c06bd4c75 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -9,10 +9,7 @@
#include "LibCxx.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+#include "llvm/ADT/ScopeExit.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/ValueObject.h"
@@ -22,7 +19,9 @@
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/VectorIterator.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ProcessStructReader.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
@@ -33,6 +32,76 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+bool lldb_private::formatters::LibcxxOptionalSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ // An optional either contains a value or not, the member __engaged_ is
+ // a bool flag, it is true if the optional has a value and false otherwise.
+ ValueObjectSP engaged_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true));
+
+ if (!engaged_sp)
+ return false;
+
+ llvm::StringRef engaged_as_cstring(
+ engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false");
+
+ stream.Printf(" Has Value=%s ", engaged_as_cstring.data());
+
+ return true;
+}
+
+bool lldb_private::formatters::LibcxxFunctionSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+
+ if (!valobj_sp)
+ return false;
+
+ ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ CPPLanguageRuntime *cpp_runtime = process->GetCPPLanguageRuntime();
+
+ if (!cpp_runtime)
+ return false;
+
+ CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info =
+ cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp);
+
+ switch (callable_info.callable_case) {
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid:
+ stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value);
+ return false;
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda:
+ stream.Printf(
+ " Lambda in File %s at Line %u",
+ callable_info.callable_line_entry.file.GetFilename().GetCString(),
+ callable_info.callable_line_entry.line);
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject:
+ stream.Printf(
+ " Function in File %s at Line %u",
+ callable_info.callable_line_entry.file.GetFilename().GetCString(),
+ callable_info.callable_line_entry.line);
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction:
+ stream.Printf(" Function = %s ",
+ callable_info.callable_symbol.GetName().GetCString());
+ break;
+ }
+
+ return true;
+}
+
bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
@@ -120,9 +189,9 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
if (!valobj_sp)
return false;
-
+
static ConstString g___i_("__i_");
-
+
// this must be a ValueObject* because it is a child of the ValueObject we
// are producing children for it if were a ValueObjectSP, we would end up
// with a loop (iterator -> synthetic -> child -> parent == iterator) and
@@ -156,37 +225,53 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
m_pair_ptr = nullptr;
return false;
}
- 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);
+ 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) {
m_pair_ptr = nullptr;
return false;
}
-
+
auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
m_pair_ptr = nullptr;
- if (addr && addr!=LLDB_INVALID_ADDRESS) {
- ClangASTContext *ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());
+ if (addr && addr != LLDB_INVALID_ADDRESS) {
+ ClangASTContext *ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());
if (!ast_ctx)
return false;
- CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), {
- {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
- {"payload",pair_type}
- });
- DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0));
+ CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
+ ConstString(),
+ {{"ptr0",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"ptr1",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"ptr2",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
+ {"payload", pair_type}});
+ llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr);
+ if (!size)
+ return false;
+ DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
ProcessSP process_sp(target_sp->GetProcessSP());
Status error;
- process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error);
+ process_sp->ReadMemory(addr, buffer_sp->GetBytes(),
+ buffer_sp->GetByteSize(), error);
if (error.Fail())
return false;
- DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
- auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type);
+ DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ auto pair_sp = CreateValueObjectFromData(
+ "pair", extractor, valobj_sp->GetExecutionContextRef(),
+ tree_node_type);
if (pair_sp)
- m_pair_sp = pair_sp->GetChildAtIndex(4,true);
+ m_pair_sp = pair_sp->GetChildAtIndex(4, true);
}
}
}
@@ -491,6 +576,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
->GetScratchClangASTContext()
->GetBasicType(lldb::eBasicTypeWChar)
.GetByteSize(nullptr);
+ if (!wchar_t_size)
+ return false;
options.SetData(extractor);
options.SetStream(&stream);
@@ -499,7 +586,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
- switch (wchar_t_size) {
+ switch (*wchar_t_size) {
case 1:
StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::UTF8>(
@@ -526,9 +613,10 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
return true;
}
-bool lldb_private::formatters::LibcxxStringSummaryProvider(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
+template <StringPrinter::StringElementType element_type>
+bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token = "") {
uint64_t size = 0;
ValueObjectSP location_sp;
@@ -557,31 +645,37 @@ bool lldb_private::formatters::LibcxxStringSummaryProvider(
options.SetData(extractor);
options.SetStream(&stream);
- options.SetPrefixToken(nullptr);
+
+ if (prefix_token.empty())
+ options.SetPrefixToken(nullptr);
+ else
+ options.SetPrefixToken(prefix_token);
+
options.SetQuote('"');
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
- StringPrinter::ReadBufferAndDumpToStream<
- StringPrinter::StringElementType::ASCII>(options);
+ StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
return true;
}
-class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd {
-public:
- LibcxxFunctionFrontEnd(ValueObject &backend)
- : SyntheticValueProviderFrontEnd(backend) {}
+bool lldb_private::formatters::LibcxxStringSummaryProviderASCII(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::ASCII>(
+ valobj, stream, summary_options);
+}
- lldb::ValueObjectSP GetSyntheticValue() override {
- static ConstString g___f_("__f_");
- return m_backend.GetChildMemberWithName(g___f_, true);
- }
-};
+bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF16>(
+ valobj, stream, summary_options, "u");
+}
-SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibcxxFunctionFrontEndCreator(
- CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- if (valobj_sp)
- return new LibcxxFunctionFrontEnd(*valobj_sp);
- return nullptr;
+bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF32>(
+ valobj, stream, summary_options, "U");
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.h b/source/Plugins/Language/CPlusPlus/LibCxx.h
index 3f6e0d6e14d7..224a540eda04 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -19,19 +19,35 @@
namespace lldb_private {
namespace formatters {
-bool LibcxxStringSummaryProvider(
+bool LibcxxStringSummaryProviderASCII(
ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options); // libc++ std::string
+ const TypeSummaryOptions &summary_options); // libc++ std::string
+
+bool LibcxxStringSummaryProviderUTF16(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options); // libc++ std::u16string
+
+bool LibcxxStringSummaryProviderUTF32(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options); // libc++ std::u32string
bool LibcxxWStringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // libc++ std::wstring
+bool LibcxxOptionalSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::optional<>
+
bool LibcxxSmartPointerSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions
&options); // libc++ std::shared_ptr<> and std::weak_ptr<>
+bool LibcxxFunctionSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::function<>
+
SyntheticChildrenFrontEnd *
LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
@@ -124,15 +140,20 @@ SyntheticChildrenFrontEnd *
LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
-SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP);
-
SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
+SyntheticChildrenFrontEnd *
+LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
+
+SyntheticChildrenFrontEnd *
+LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp);
+
} // namespace formatters
} // namespace lldb_private
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 0cdb0b26cf3b..489ac4d96072 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -79,17 +79,24 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
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 {
+ if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) {
+ llvm::Optional<uint64_t> bit_size =
+ type.GetBitSize(ctx.GetBestExecutionContextScope());
+ if (!bit_size || *bit_size == 0)
+ return {};
+ chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
+ } else {
type = m_first->GetCompilerType();
chunk = m_first;
}
if (!type || !chunk)
- return ValueObjectSP();
+ return {};
- size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope());
+ llvm::Optional<uint64_t> bit_size =
+ type.GetBitSize(ctx.GetBestExecutionContextScope());
+ if (!bit_size || *bit_size == 0)
+ return {};
+ size_t chunk_idx = idx % *bit_size;
uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
index 5823f6f3e038..390483d02668 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LibCxx.h"
#include "lldb/Core/ValueObject.h"
@@ -98,12 +94,11 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd::
if (!m_element_type.IsValid())
return false;
- m_element_size = m_element_type.GetByteSize(nullptr);
-
- if (m_element_size > 0)
- m_start =
- m_backend.GetChildMemberWithName(g___begin_, true)
- .get(); // store raw pointers or end up with a circular dependency
+ if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) {
+ m_element_size = *size;
+ // Store raw pointers or end up with a circular dependency.
+ m_start = m_backend.GetChildMemberWithName(g___begin_, true).get();
+ }
return false;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 6066f14b18cc..81606b573cea 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LibCxx.h"
#include "lldb/Core/ValueObject.h"
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 8f82bdcbfd59..429569d57928 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LibCxx.h"
#include "lldb/Core/ValueObject.h"
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
new file mode 100644
index 000000000000..762b824f262a
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -0,0 +1,85 @@
+//===-- LibCxxOptional.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 OptionalFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ OptionalFrontEnd(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_size; }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ size_t m_size = 0;
+ ValueObjectSP m_base_sp;
+};
+} // namespace
+
+bool OptionalFrontEnd::Update() {
+ ValueObjectSP engaged_sp(
+ m_backend.GetChildMemberWithName(ConstString("__engaged_"), true));
+
+ if (!engaged_sp)
+ return false;
+
+ // __engaged_ is a bool flag and is true if the optional contains a value.
+ // Converting it to unsigned gives us a size of 1 if it contains a value
+ // and 0 if not.
+ m_size = engaged_sp->GetValueAsUnsigned(0);
+
+ return false;
+}
+
+ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_size)
+ return ValueObjectSP();
+
+ // __val_ contains the underlying value of an optional if it has one.
+ // Currently because it is part of an anonymous union GetChildMemberWithName()
+ // does not peer through and find it unless we are at the parent itself.
+ // We can obtain the parent through __engaged_.
+ ValueObjectSP val_sp(
+ m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)
+ ->GetParent()
+ ->GetChildAtIndex(0, true)
+ ->GetChildMemberWithName(ConstString("__val_"), true));
+
+ if (!val_sp)
+ return ValueObjectSP();
+
+ CompilerType holder_type = val_sp->GetCompilerType();
+
+ if (!holder_type)
+ return ValueObjectSP();
+
+ return val_sp->Clone(ConstString(llvm::formatv("Value").str()));
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new OptionalFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 0f1c2537d651..51ae8cb3184c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LibCxx.h"
#include "lldb/Core/ValueObject.h"
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
new file mode 100644
index 000000000000..e874616c3251
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
@@ -0,0 +1,256 @@
+//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxxVariant.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ScopeExit.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+// libc++ variant implementation contains two members that we care about both
+// are contained in the __impl member.
+// - __index which tells us which of the variadic template types is the active
+// type for the variant
+// - __data is a variadic union which recursively contains itself as member
+// which refers to the tailing variadic types.
+// - __head which refers to the leading non pack type
+// - __value refers to the actual value contained
+// - __tail which refers to the remaining pack types
+//
+// e.g. given std::variant<int,double,char> v1
+//
+// (lldb) frame var -R v1.__impl.__data
+//(... __union<... 0, int, double, char>) v1.__impl.__data = {
+// ...
+// __head = {
+// __value = ...
+// }
+// __tail = {
+// ...
+// __head = {
+// __value = ...
+// }
+// __tail = {
+// ...
+// __head = {
+// __value = ...
+// ...
+//
+// So given
+// - __index equal to 0 the active value is contained in
+//
+// __data.__head.__value
+//
+// - __index equal to 1 the active value is contained in
+//
+// __data.__tail.__head.__value
+//
+// - __index equal to 2 the active value is contained in
+//
+// __data.__tail.__tail.__head.__value
+//
+
+namespace {
+// libc++ std::variant index could have one of three states
+// 1) VALID, we can obtain it and its not variant_npos
+// 2) INVALID, we can't obtain it or it is not a type we expect
+// 3) NPOS, its value is variant_npos which means the variant has no value
+enum class LibcxxVariantIndexValidity { VALID, INVALID, NPOS };
+
+LibcxxVariantIndexValidity
+LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) {
+ ValueObjectSP index_sp(
+ impl_sp->GetChildMemberWithName(ConstString("__index"), true));
+
+ if (!index_sp)
+ return LibcxxVariantIndexValidity::INVALID;
+
+ int64_t index_value = index_sp->GetValueAsSigned(0);
+
+ if (index_value == -1)
+ return LibcxxVariantIndexValidity::NPOS;
+
+ return LibcxxVariantIndexValidity::VALID;
+}
+
+llvm::Optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) {
+ ValueObjectSP index_sp(
+ impl_sp->GetChildMemberWithName(ConstString("__index"), true));
+
+ if (!index_sp)
+ return {};
+
+ return {index_sp->GetValueAsUnsigned(0)};
+}
+
+ValueObjectSP LibcxxVariantGetNthHead(ValueObjectSP &impl_sp, uint64_t index) {
+ ValueObjectSP data_sp(
+ impl_sp->GetChildMemberWithName(ConstString("__data"), true));
+
+ if (!data_sp)
+ return ValueObjectSP{};
+
+ ValueObjectSP current_level = data_sp;
+ for (uint64_t n = index; n != 0; --n) {
+ ValueObjectSP tail_sp(
+ current_level->GetChildMemberWithName(ConstString("__tail"), true));
+
+ if (!tail_sp)
+ return ValueObjectSP{};
+
+ current_level = tail_sp;
+ }
+
+ return current_level->GetChildMemberWithName(ConstString("__head"), true);
+}
+} // namespace
+
+namespace lldb_private {
+namespace formatters {
+bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP impl_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__impl"), true));
+
+ if (!impl_sp)
+ return false;
+
+ LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
+
+ if (validity == LibcxxVariantIndexValidity::INVALID)
+ return false;
+
+ if (validity == LibcxxVariantIndexValidity::NPOS) {
+ stream.Printf(" No Value");
+ return true;
+ }
+
+ auto optional_index_value = LibcxxVariantIndexValue(impl_sp);
+
+ if (!optional_index_value)
+ return false;
+
+ uint64_t index_value = *optional_index_value;
+
+ ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value);
+
+ if (!nth_head)
+ return false;
+
+ CompilerType head_type = nth_head->GetCompilerType();
+
+ if (!head_type)
+ return false;
+
+ CompilerType template_type = head_type.GetTypeTemplateArgument(1);
+
+ if (!template_type)
+ return false;
+
+ stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString());
+
+ return true;
+}
+} // namespace formatters
+} // namespace lldb_private
+
+namespace {
+class VariantFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ VariantFrontEnd(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_size; }
+ ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+private:
+ size_t m_size = 0;
+ ValueObjectSP m_base_sp;
+};
+} // namespace
+
+bool VariantFrontEnd::Update() {
+ m_size = 0;
+ ValueObjectSP impl_sp(
+ m_backend.GetChildMemberWithName(ConstString("__impl"), true));
+ if (!impl_sp)
+ return false;
+
+ LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp);
+
+ if (validity == LibcxxVariantIndexValidity::INVALID)
+ return false;
+
+ if (validity == LibcxxVariantIndexValidity::NPOS)
+ return true;
+
+ m_size = 1;
+
+ return false;
+}
+
+ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) {
+ if (idx >= m_size)
+ return ValueObjectSP();
+
+ ValueObjectSP impl_sp(
+ m_backend.GetChildMemberWithName(ConstString("__impl"), true));
+
+ auto optional_index_value = LibcxxVariantIndexValue(impl_sp);
+
+ if (!optional_index_value)
+ return ValueObjectSP();
+
+ uint64_t index_value = *optional_index_value;
+
+ ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value);
+
+ if (!nth_head)
+ return ValueObjectSP();
+
+ CompilerType head_type = nth_head->GetCompilerType();
+
+ if (!head_type)
+ return ValueObjectSP();
+
+ CompilerType template_type = head_type.GetTypeTemplateArgument(1);
+
+ if (!template_type)
+ return ValueObjectSP();
+
+ ValueObjectSP head_value(
+ nth_head->GetChildMemberWithName(ConstString("__value"), true));
+
+ if (!head_value)
+ return ValueObjectSP();
+
+ return head_value->Clone(ConstString(ConstString("Value").AsCString()));
+}
+
+SyntheticChildrenFrontEnd *
+formatters::LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP valobj_sp) {
+ if (valobj_sp)
+ return new VariantFrontEnd(*valobj_sp);
+ return nullptr;
+}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
new file mode 100644
index 000000000000..04834581963f
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.h
@@ -0,0 +1,31 @@
+//===-- LibCxxVariant.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_LibCxxVariant_h_
+#define liblldb_LibCxxVariant_h_
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+#include "lldb/Utility/Stream.h"
+
+namespace lldb_private {
+namespace formatters {
+bool LibcxxVariantSummaryProvider(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // libc++ std::variant<>
+
+SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+} // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_LibCxxVariant_h_
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index 711130639cd2..ed405c875174 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LibCxx.h"
#include "lldb/Core/ValueObject.h"
@@ -149,14 +145,16 @@ bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() {
if (!data_type_finder_sp)
return false;
m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
- m_element_size = m_element_type.GetByteSize(nullptr);
-
- if (m_element_size > 0) {
- // store raw pointers or end up with a circular dependency
- m_start =
- m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get();
- m_finish =
- m_backend.GetChildMemberWithName(ConstString("__end_"), true).get();
+ if (llvm::Optional<uint64_t> size = m_element_type.GetByteSize(nullptr)) {
+ m_element_size = *size;
+
+ if (m_element_size > 0) {
+ // store raw pointers or end up with a circular dependency
+ m_start =
+ m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get();
+ m_finish =
+ m_backend.GetChildMemberWithName(ConstString("__end_"), true).get();
+ }
}
return false;
}
@@ -196,27 +194,29 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex(
if (iter != end)
return iter->second;
if (idx >= m_count)
- return ValueObjectSP();
+ return {};
if (m_base_data_address == 0 || m_count == 0)
- return ValueObjectSP();
+ return {};
if (!m_bool_type)
- return ValueObjectSP();
+ return {};
size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
lldb::addr_t byte_location = m_base_data_address + byte_idx;
ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
if (!process_sp)
- return ValueObjectSP();
+ return {};
uint8_t byte = 0;
uint8_t mask = 0;
Status err;
size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
if (err.Fail() || bytes_read == 0)
- return ValueObjectSP();
+ return {};
mask = 1 << bit_index;
bool bit_set = ((byte & mask) != 0);
- DataBufferSP buffer_sp(
- new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0));
+ llvm::Optional<uint64_t> size = m_bool_type.GetByteSize(nullptr);
+ if (!size)
+ return {};
+ DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
if (bit_set && buffer_sp && buffer_sp->GetBytes()) {
// regardless of endianness, anything non-zero is true
*(buffer_sp->GetBytes()) = 1;
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
index 3e2b7159f894..695371fc3992 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
@@ -9,10 +9,6 @@
#include "LibStdcpp.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/StringPrinter.h"
@@ -301,8 +297,11 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider(
if (!wchar_compiler_type)
return false;
- const uint32_t wchar_size = wchar_compiler_type.GetBitSize(
- nullptr); // Safe to pass NULL for exe_scope here
+ // Safe to pass nullptr for exe_scope here.
+ llvm::Optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
+ if (!size)
+ return false;
+ const uint32_t wchar_size = *size;
StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
Status error;
diff --git a/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
new file mode 100644
index 000000000000..84f03e0e3016
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
@@ -0,0 +1,99 @@
+//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MSVCUndecoratedNameParser.h"
+
+#include <stack>
+
+MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) {
+ std::size_t last_base_start = 0;
+
+ std::stack<std::size_t> stack;
+ unsigned int open_angle_brackets = 0;
+ for (size_t i = 0; i < name.size(); i++) {
+ switch (name[i]) {
+ case '<':
+ // Do not treat `operator<' and `operator<<' as templates
+ // (sometimes they represented as `<' and `<<' in the name).
+ if (i == last_base_start ||
+ (i == last_base_start + 1 && name[last_base_start] == '<'))
+ break;
+
+ stack.push(i);
+ open_angle_brackets++;
+
+ break;
+ case '>':
+ if (!stack.empty() && name[stack.top()] == '<') {
+ open_angle_brackets--;
+ stack.pop();
+ }
+
+ break;
+ case '`':
+ stack.push(i);
+
+ break;
+ case '\'':
+ while (!stack.empty()) {
+ std::size_t top = stack.top();
+ if (name[top] == '<')
+ open_angle_brackets--;
+
+ stack.pop();
+
+ if (name[top] == '`')
+ break;
+ }
+
+ break;
+ case ':':
+ if (open_angle_brackets)
+ break;
+ if (i == 0 || name[i - 1] != ':')
+ break;
+
+ m_specifiers.emplace_back(name.take_front(i - 1),
+ name.slice(last_base_start, i - 1));
+
+ last_base_start = i + 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ m_specifiers.emplace_back(name, name.drop_front(last_base_start));
+}
+
+bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {
+ return name.find('`') != llvm::StringRef::npos;
+}
+
+bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
+ llvm::StringRef name, llvm::StringRef &context,
+ llvm::StringRef &identifier) {
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+ std::size_t count = specs.size();
+ identifier = count > 0 ? specs[count - 1].GetBaseName() : "";
+ context = count > 1 ? specs[count - 2].GetFullName() : "";
+
+ return count;
+}
+
+llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+ if (specs.empty())
+ return "";
+
+ return specs[specs.size() - 1].GetBaseName();
+}
diff --git a/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
new file mode 100644
index 000000000000..0c49100d8d49
--- /dev/null
+++ b/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
@@ -0,0 +1,51 @@
+//===-- MSVCUndecoratedNameParser.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_MSVCUndecoratedNameParser_h_
+#define liblldb_MSVCUndecoratedNameParser_h_
+
+#include <vector>
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+class MSVCUndecoratedNameSpecifier {
+public:
+ MSVCUndecoratedNameSpecifier(llvm::StringRef full_name,
+ llvm::StringRef base_name)
+ : m_full_name(full_name), m_base_name(base_name) {}
+
+ llvm::StringRef GetFullName() const { return m_full_name; }
+ llvm::StringRef GetBaseName() const { return m_base_name; }
+
+private:
+ llvm::StringRef m_full_name;
+ llvm::StringRef m_base_name;
+};
+
+class MSVCUndecoratedNameParser {
+public:
+ explicit MSVCUndecoratedNameParser(llvm::StringRef name);
+
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> GetSpecifiers() const {
+ return m_specifiers;
+ }
+
+ static bool IsMSVCUndecoratedName(llvm::StringRef name);
+ static bool ExtractContextAndIdentifier(llvm::StringRef name,
+ llvm::StringRef &context,
+ llvm::StringRef &identifier);
+
+ static llvm::StringRef DropScope(llvm::StringRef name);
+
+private:
+ std::vector<MSVCUndecoratedNameSpecifier> m_specifiers;
+};
+
+#endif
diff --git a/source/Plugins/Language/ClangCommon/CMakeLists.txt b/source/Plugins/Language/ClangCommon/CMakeLists.txt
new file mode 100644
index 000000000000..854320dd312e
--- /dev/null
+++ b/source/Plugins/Language/ClangCommon/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_lldb_library(lldbPluginClangCommon PLUGIN
+ ClangHighlighter.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+)
diff --git a/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
new file mode 100644
index 000000000000..1fe8482263eb
--- /dev/null
+++ b/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp
@@ -0,0 +1,237 @@
+//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangHighlighter.h"
+
+#include "lldb/Target/Language.h"
+#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/Utility/StreamString.h"
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace lldb_private;
+
+bool ClangHighlighter::isKeyword(llvm::StringRef token) const {
+ return keywords.find(token) != keywords.end();
+}
+
+ClangHighlighter::ClangHighlighter() {
+#define KEYWORD(X, N) keywords.insert(#X);
+#include "clang/Basic/TokenKinds.def"
+}
+
+/// Determines which style should be applied to the given token.
+/// \param highlighter
+/// The current highlighter that should use the style.
+/// \param token
+/// The current token.
+/// \param tok_str
+/// The string in the source code the token represents.
+/// \param options
+/// The style we use for coloring the source code.
+/// \param in_pp_directive
+/// If we are currently in a preprocessor directive. NOTE: This is
+/// passed by reference and will be updated if the current token starts
+/// or ends a preprocessor directive.
+/// \return
+/// The ColorStyle that should be applied to the token.
+static HighlightStyle::ColorStyle
+determineClangStyle(const ClangHighlighter &highlighter,
+ const clang::Token &token, llvm::StringRef tok_str,
+ const HighlightStyle &options, bool &in_pp_directive) {
+ using namespace clang;
+
+ if (token.is(tok::comment)) {
+ // If we were in a preprocessor directive before, we now left it.
+ in_pp_directive = false;
+ return options.comment;
+ } else if (in_pp_directive || token.getKind() == tok::hash) {
+ // Let's assume that the rest of the line is a PP directive.
+ in_pp_directive = true;
+ // Preprocessor directives are hard to match, so we have to hack this in.
+ return options.pp_directive;
+ } else if (tok::isStringLiteral(token.getKind()))
+ return options.string_literal;
+ else if (tok::isLiteral(token.getKind()))
+ return options.scalar_literal;
+ else if (highlighter.isKeyword(tok_str))
+ return options.keyword;
+ else
+ switch (token.getKind()) {
+ case tok::raw_identifier:
+ case tok::identifier:
+ return options.identifier;
+ case tok::l_brace:
+ case tok::r_brace:
+ return options.braces;
+ case tok::l_square:
+ case tok::r_square:
+ return options.square_brackets;
+ case tok::l_paren:
+ case tok::r_paren:
+ return options.parentheses;
+ case tok::comma:
+ return options.comma;
+ case tok::coloncolon:
+ case tok::colon:
+ return options.colon;
+
+ case tok::amp:
+ case tok::ampamp:
+ case tok::ampequal:
+ case tok::star:
+ case tok::starequal:
+ case tok::plus:
+ case tok::plusplus:
+ case tok::plusequal:
+ case tok::minus:
+ case tok::arrow:
+ case tok::minusminus:
+ case tok::minusequal:
+ case tok::tilde:
+ case tok::exclaim:
+ case tok::exclaimequal:
+ case tok::slash:
+ case tok::slashequal:
+ case tok::percent:
+ case tok::percentequal:
+ case tok::less:
+ case tok::lessless:
+ case tok::lessequal:
+ case tok::lesslessequal:
+ case tok::spaceship:
+ case tok::greater:
+ case tok::greatergreater:
+ case tok::greaterequal:
+ case tok::greatergreaterequal:
+ case tok::caret:
+ case tok::caretequal:
+ case tok::pipe:
+ case tok::pipepipe:
+ case tok::pipeequal:
+ case tok::question:
+ case tok::equal:
+ case tok::equalequal:
+ return options.operators;
+ default:
+ break;
+ }
+ return HighlightStyle::ColorStyle();
+}
+
+void ClangHighlighter::Highlight(const HighlightStyle &options,
+ llvm::StringRef line,
+ llvm::Optional<size_t> cursor_pos,
+ llvm::StringRef previous_lines,
+ Stream &result) const {
+ using namespace clang;
+
+ FileSystemOptions file_opts;
+ FileManager file_mgr(file_opts);
+
+ unsigned line_number = previous_lines.count('\n') + 1U;
+
+ // Let's build the actual source code Clang needs and setup some utility
+ // objects.
+ std::string full_source = previous_lines.str() + line.str();
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
+ llvm::IntrusiveRefCntPtr<DiagnosticOptions> diags_opts(
+ new DiagnosticOptions());
+ DiagnosticsEngine diags(diag_ids, diags_opts);
+ clang::SourceManager SM(diags, file_mgr);
+ auto buf = llvm::MemoryBuffer::getMemBuffer(full_source);
+
+ FileID FID = SM.createFileID(clang::SourceManager::Unowned, buf.get());
+
+ // Let's just enable the latest ObjC and C++ which should get most tokens
+ // right.
+ LangOptions Opts;
+ Opts.ObjC = true;
+ // FIXME: This should probably set CPlusPlus, CPlusPlus11, ... too
+ Opts.CPlusPlus17 = true;
+ Opts.LineComment = true;
+
+ Lexer lex(FID, buf.get(), SM, Opts);
+ // The lexer should keep whitespace around.
+ lex.SetKeepWhitespaceMode(true);
+
+ // Keeps track if we have entered a PP directive.
+ bool in_pp_directive = false;
+
+ // True once we actually lexed the user provided line.
+ bool found_user_line = false;
+
+ // True if we already highlighted the token under the cursor, false otherwise.
+ bool highlighted_cursor = false;
+ Token token;
+ bool exit = false;
+ while (!exit) {
+ // Returns true if this is the last token we get from the lexer.
+ exit = lex.LexFromRawLexer(token);
+
+ bool invalid = false;
+ unsigned current_line_number =
+ SM.getSpellingLineNumber(token.getLocation(), &invalid);
+ if (current_line_number != line_number)
+ continue;
+ found_user_line = true;
+
+ // We don't need to print any tokens without a spelling line number.
+ if (invalid)
+ continue;
+
+ // Same as above but with the column number.
+ invalid = false;
+ unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid);
+ if (invalid)
+ continue;
+ // Column numbers start at 1, but indexes in our string start at 0.
+ --start;
+
+ // Annotations don't have a length, so let's skip them.
+ if (token.isAnnotation())
+ continue;
+
+ // Extract the token string from our source code.
+ llvm::StringRef tok_str = line.substr(start, token.getLength());
+
+ // If the token is just an empty string, we can skip all the work below.
+ if (tok_str.empty())
+ continue;
+
+ // If the cursor is inside this token, we have to apply the 'selected'
+ // highlight style before applying the actual token color.
+ llvm::StringRef to_print = tok_str;
+ StreamString storage;
+ auto end = start + token.getLength();
+ if (cursor_pos && end > *cursor_pos && !highlighted_cursor) {
+ highlighted_cursor = true;
+ options.selected.Apply(storage, tok_str);
+ to_print = storage.GetString();
+ }
+
+ // See how we are supposed to highlight this token.
+ HighlightStyle::ColorStyle color =
+ determineClangStyle(*this, token, tok_str, options, in_pp_directive);
+
+ color.Apply(result, to_print);
+ }
+
+ // If we went over the whole file but couldn't find our own file, then
+ // somehow our setup was wrong. When we're in release mode we just give the
+ // user the normal line and pretend we don't know how to highlight it. In
+ // debug mode we bail out with an assert as this should never happen.
+ if (!found_user_line) {
+ result << line;
+ assert(false && "We couldn't find the user line in the input file?");
+ }
+}
diff --git a/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/source/Plugins/Language/ClangCommon/ClangHighlighter.h
new file mode 100644
index 000000000000..579c4315228f
--- /dev/null
+++ b/source/Plugins/Language/ClangCommon/ClangHighlighter.h
@@ -0,0 +1,38 @@
+//===-- ClangHighlighter.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_ClangHighlighter_h_
+#define liblldb_ClangHighlighter_h_
+
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/StringSet.h"
+
+#include "lldb/Core/Highlighter.h"
+
+namespace lldb_private {
+
+class ClangHighlighter : public Highlighter {
+ llvm::StringSet<> keywords;
+
+public:
+ ClangHighlighter();
+ llvm::StringRef GetName() const override { return "clang"; }
+
+ void Highlight(const HighlightStyle &options, llvm::StringRef line,
+ llvm::Optional<size_t> cursor_pos,
+ llvm::StringRef previous_lines, Stream &s) const override;
+
+ /// Returns true if the given string represents a keywords in any Clang
+ /// supported language.
+ bool isKeyword(llvm::StringRef token) const;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ClangHighlighter_h_
diff --git a/source/Plugins/Language/Go/CMakeLists.txt b/source/Plugins/Language/Go/CMakeLists.txt
deleted file mode 100644
index 793e417a618a..000000000000
--- a/source/Plugins/Language/Go/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-add_lldb_library(lldbPluginGoLanguage PLUGIN
- GoLanguage.cpp
- GoFormatterFunctions.cpp
-
- LINK_LIBS
- clangAST
- lldbCore
- lldbDataFormatters
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
-)
diff --git a/source/Plugins/Language/Go/GoFormatterFunctions.cpp b/source/Plugins/Language/Go/GoFormatterFunctions.cpp
deleted file mode 100644
index aac75205c6ef..000000000000
--- a/source/Plugins/Language/Go/GoFormatterFunctions.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-//===-- GoFormatterFunctions.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
-#include <map>
-
-// Other libraries and framework includes
-// Project includes
-#include "GoFormatterFunctions.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/DataFormatters/StringPrinter.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::formatters;
-
-namespace {
-class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- GoSliceSyntheticFrontEnd(ValueObject &valobj)
- : SyntheticChildrenFrontEnd(valobj) {
- Update();
- }
-
- ~GoSliceSyntheticFrontEnd() override = default;
-
- size_t CalculateNumChildren() override { return m_len; }
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
- if (idx < m_len) {
- ValueObjectSP &cached = m_children[idx];
- if (!cached) {
- StreamString idx_name;
- idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- lldb::addr_t object_at_idx = m_base_data_address;
- object_at_idx += idx * m_type.GetByteSize(nullptr);
- cached = CreateValueObjectFromAddress(
- idx_name.GetString(), object_at_idx,
- m_backend.GetExecutionContextRef(), m_type);
- }
- return cached;
- }
- return ValueObjectSP();
- }
-
- bool Update() override {
- size_t old_count = m_len;
-
- ConstString array_const_str("array");
- ValueObjectSP array_sp =
- m_backend.GetChildMemberWithName(array_const_str, true);
- if (!array_sp) {
- m_children.clear();
- return old_count == 0;
- }
- m_type = array_sp->GetCompilerType().GetPointeeType();
- m_base_data_address = array_sp->GetPointerValue();
-
- ConstString len_const_str("len");
- ValueObjectSP len_sp =
- m_backend.GetChildMemberWithName(len_const_str, true);
- if (len_sp) {
- m_len = len_sp->GetValueAsUnsigned(0);
- m_children.clear();
- }
-
- return old_count == m_len;
- }
-
- bool MightHaveChildren() override { return true; }
-
- size_t GetIndexOfChildWithName(const ConstString &name) override {
- return ExtractIndexFromString(name.AsCString());
- }
-
-private:
- CompilerType m_type;
- lldb::addr_t m_base_data_address;
- size_t m_len;
- std::map<size_t, lldb::ValueObjectSP> m_children;
-};
-
-} // anonymous namespace
-
-bool lldb_private::formatters::GoStringSummaryProvider(
- ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- if (valobj.IsPointerType()) {
- Status err;
- ValueObjectSP deref = valobj.Dereference(err);
- if (!err.Success())
- return false;
- return GoStringSummaryProvider(*deref, stream, opts);
- }
-
- ConstString str_name("str");
- ConstString len_name("len");
-
- ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true);
- ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true);
- if (!data_sp || !len_sp)
- return false;
- bool success;
- lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success);
-
- if (!success)
- return false;
-
- uint64_t length = len_sp->GetValueAsUnsigned(0);
- if (length == 0) {
- stream.Printf("\"\"");
- return true;
- }
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(valobj_addr);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetSourceSize(length);
- options.SetNeedsZeroTermination(false);
- options.SetLanguage(eLanguageTypeGo);
-
- if (!StringPrinter::ReadStringAndDumpToStream<
- StringPrinter::StringElementType::UTF8>(options)) {
- stream.Printf("Summary Unavailable");
- return true;
- }
-
- return true;
-}
-
-SyntheticChildrenFrontEnd *
-lldb_private::formatters::GoSliceSyntheticFrontEndCreator(
- CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- if (!valobj_sp)
- return nullptr;
-
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return nullptr;
- return new GoSliceSyntheticFrontEnd(*valobj_sp);
-}
diff --git a/source/Plugins/Language/Go/GoFormatterFunctions.h b/source/Plugins/Language/Go/GoFormatterFunctions.h
deleted file mode 100644
index 1bf1892d6669..000000000000
--- a/source/Plugins/Language/Go/GoFormatterFunctions.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- GoFormatterFunctions.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_GoFormatterFunctions_h_
-#define liblldb_GoFormatterFunctions_h_
-
-// C Includes
-#include <stdint.h>
-#include <time.h>
-
-// C++ Includes
-// Other libraries and framework includes
-#include "clang/AST/ASTContext.h"
-
-// Project includes
-#include "lldb/lldb-forward.h"
-
-#include "lldb/DataFormatters/FormatClasses.h"
-#include "lldb/DataFormatters/TypeSynthetic.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ConstString.h"
-
-namespace lldb_private {
-namespace formatters {
-
-bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options);
-
-SyntheticChildrenFrontEnd *
-GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
-
-} // namespace formatters
-} // namespace lldb_private
-
-#endif // liblldb_GoFormatterFunctions_h_
diff --git a/source/Plugins/Language/Go/GoLanguage.cpp b/source/Plugins/Language/Go/GoLanguage.cpp
deleted file mode 100644
index 66b4530abc76..000000000000
--- a/source/Plugins/Language/Go/GoLanguage.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- GoLanguage.cpp ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-#include <string.h>
-// C++ Includes
-#include <functional>
-#include <mutex>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Threading.h"
-
-// Project includes
-#include "GoLanguage.h"
-#include "Plugins/Language/Go/GoFormatterFunctions.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "lldb/Utility/ConstString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::formatters;
-
-void GoLanguage::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language",
- CreateInstance);
-}
-
-void GoLanguage::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString GoLanguage::GetPluginNameStatic() {
- static ConstString g_name("Go");
- return g_name;
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString GoLanguage::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t GoLanguage::GetPluginVersion() { return 1; }
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-Language *GoLanguage::CreateInstance(lldb::LanguageType language) {
- if (language == eLanguageTypeGo)
- return new GoLanguage();
- return nullptr;
-}
-
-HardcodedFormatters::HardcodedSummaryFinder
-GoLanguage::GetHardcodedSummaries() {
- static llvm::once_flag g_initialize;
- static HardcodedFormatters::HardcodedSummaryFinder g_formatters;
-
- llvm::call_once(g_initialize, []() -> void {
- g_formatters.push_back(
- [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
- FormatManager &) -> TypeSummaryImpl::SharedPointer {
- static CXXFunctionSummaryFormat::SharedPointer formatter_sp(
- new CXXFunctionSummaryFormat(
- TypeSummaryImpl::Flags().SetDontShowChildren(true),
- lldb_private::formatters::GoStringSummaryProvider,
- "Go string summary provider"));
- if (GoASTContext::IsGoString(valobj.GetCompilerType())) {
- return formatter_sp;
- }
- if (GoASTContext::IsGoString(
- valobj.GetCompilerType().GetPointeeType())) {
- return formatter_sp;
- }
- return nullptr;
- });
- g_formatters.push_back(
- [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
- FormatManager &) -> TypeSummaryImpl::SharedPointer {
- static lldb::TypeSummaryImplSP formatter_sp(new StringSummaryFormat(
- TypeSummaryImpl::Flags().SetHideItemNames(true),
- "(len ${var.len}, cap ${var.cap})"));
- if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) {
- return formatter_sp;
- }
- if (GoASTContext::IsGoSlice(
- valobj.GetCompilerType().GetPointeeType())) {
- return formatter_sp;
- }
- return nullptr;
- });
- });
- return g_formatters;
-}
-
-HardcodedFormatters::HardcodedSyntheticFinder
-GoLanguage::GetHardcodedSynthetics() {
- static llvm::once_flag g_initialize;
- static HardcodedFormatters::HardcodedSyntheticFinder g_formatters;
-
- llvm::call_once(g_initialize, []() -> void {
- g_formatters.push_back(
- [](lldb_private::ValueObject &valobj, lldb::DynamicValueType,
- FormatManager &fmt_mgr) -> SyntheticChildren::SharedPointer {
- static CXXSyntheticChildren::SharedPointer formatter_sp(
- new CXXSyntheticChildren(
- SyntheticChildren::Flags(), "slice synthetic children",
- lldb_private::formatters::GoSliceSyntheticFrontEndCreator));
- if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) {
- return formatter_sp;
- }
- return nullptr;
- });
- });
-
- return g_formatters;
-}
diff --git a/source/Plugins/Language/Go/GoLanguage.h b/source/Plugins/Language/Go/GoLanguage.h
deleted file mode 100644
index ebec1d7205fa..000000000000
--- a/source/Plugins/Language/Go/GoLanguage.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- GoLanguage.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_GoLanguage_h_
-#define liblldb_GoLanguage_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
-// Project includes
-#include "lldb/Target/Language.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class GoLanguage : public Language {
-public:
- GoLanguage() = default;
-
- ~GoLanguage() override = default;
-
- lldb::LanguageType GetLanguageType() const override {
- return lldb::eLanguageTypeGo;
- }
-
- HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override;
-
- HardcodedFormatters::HardcodedSyntheticFinder
- GetHardcodedSynthetics() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::Language *CreateInstance(lldb::LanguageType language);
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_GoLanguage_h_
diff --git a/source/Plugins/Language/Java/CMakeLists.txt b/source/Plugins/Language/Java/CMakeLists.txt
deleted file mode 100644
index f0cbcd8d3f59..000000000000
--- a/source/Plugins/Language/Java/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_lldb_library(lldbPluginJavaLanguage PLUGIN
- JavaFormatterFunctions.cpp
- JavaLanguage.cpp
-
- LINK_LIBS
- lldbCore
- lldbDataFormatters
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
-)
diff --git a/source/Plugins/Language/Java/JavaFormatterFunctions.cpp b/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
deleted file mode 100644
index 498795c90be8..000000000000
--- a/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-//===-- JavaFormatterFunctions.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 "JavaFormatterFunctions.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/DataFormatters/StringPrinter.h"
-#include "lldb/Symbol/JavaASTContext.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::formatters;
-
-namespace {
-
-class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
-public:
- JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
- : SyntheticChildrenFrontEnd(*valobj_sp) {
- if (valobj_sp)
- Update();
- }
-
- size_t CalculateNumChildren() override {
- ValueObjectSP valobj = GetDereferencedValueObject();
- if (!valobj)
- return 0;
-
- CompilerType type = valobj->GetCompilerType();
- uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj);
- if (size == UINT32_MAX)
- return 0;
- return size;
- }
-
- lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
- ValueObjectSP valobj = GetDereferencedValueObject();
- if (!valobj)
- return nullptr;
-
- ProcessSP process_sp = valobj->GetProcessSP();
- if (!process_sp)
- return nullptr;
-
- CompilerType type = valobj->GetCompilerType();
- CompilerType element_type = type.GetArrayElementType();
- lldb::addr_t address =
- valobj->GetAddressOf() +
- JavaASTContext::CalculateArrayElementOffset(type, idx);
-
- Status error;
- size_t byte_size = element_type.GetByteSize(nullptr);
- DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
- size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(),
- byte_size, error);
- if (error.Fail() || byte_size != bytes_read)
- return nullptr;
-
- StreamString name;
- name.Printf("[%" PRIu64 "]", (uint64_t)idx);
- DataExtractor data(buffer_sp, process_sp->GetByteOrder(),
- process_sp->GetAddressByteSize());
- return CreateValueObjectFromData(
- name.GetString(), data, valobj->GetExecutionContextRef(), element_type);
- }
-
- bool Update() override { return false; }
-
- bool MightHaveChildren() override { return true; }
-
- size_t GetIndexOfChildWithName(const ConstString &name) override {
- return ExtractIndexFromString(name.GetCString());
- }
-
-private:
- ValueObjectSP GetDereferencedValueObject() {
- if (!m_backend.IsPointerOrReferenceType())
- return m_backend.GetSP();
-
- Status error;
- return m_backend.Dereference(error);
- }
-};
-
-} // end of anonymous namespace
-
-bool lldb_private::formatters::JavaStringSummaryProvider(
- ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
- if (valobj.IsPointerOrReferenceType()) {
- Status error;
- ValueObjectSP deref = valobj.Dereference(error);
- if (error.Fail())
- return false;
- return JavaStringSummaryProvider(*deref, stream, opts);
- }
-
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ConstString data_name("value");
- ConstString length_name("count");
-
- ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true);
- ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true);
- if (!data_sp || !length_sp)
- return false;
-
- bool success = false;
- uint64_t length = length_sp->GetValueAsUnsigned(0, &success);
- if (!success)
- return false;
-
- if (length == 0) {
- stream.Printf("\"\"");
- return true;
- }
- lldb::addr_t valobj_addr = data_sp->GetAddressOf();
-
- StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
- options.SetLocation(valobj_addr);
- options.SetProcessSP(process_sp);
- options.SetStream(&stream);
- options.SetSourceSize(length);
- options.SetNeedsZeroTermination(false);
- options.SetLanguage(eLanguageTypeJava);
-
- if (StringPrinter::ReadStringAndDumpToStream<
- StringPrinter::StringElementType::UTF16>(options))
- return true;
-
- stream.Printf("Summary Unavailable");
- return true;
-}
-
-bool lldb_private::formatters::JavaArraySummaryProvider(
- ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
- if (valobj.IsPointerOrReferenceType()) {
- Status error;
- ValueObjectSP deref = valobj.Dereference(error);
- if (error.Fail())
- return false;
- return JavaArraySummaryProvider(*deref, stream, options);
- }
-
- CompilerType type = valobj.GetCompilerType();
- uint32_t size = JavaASTContext::CalculateArraySize(type, valobj);
- if (size == UINT32_MAX)
- return false;
- stream.Printf("[%u]{...}", size);
- return true;
-}
-
-SyntheticChildrenFrontEnd *
-lldb_private::formatters::JavaArraySyntheticFrontEndCreator(
- CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr;
-}
diff --git a/source/Plugins/Language/Java/JavaFormatterFunctions.h b/source/Plugins/Language/Java/JavaFormatterFunctions.h
deleted file mode 100644
index d1983429529c..000000000000
--- a/source/Plugins/Language/Java/JavaFormatterFunctions.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- JavaFormatterFunctions.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_JavaFormatterFunctions_h_
-#define liblldb_JavaFormatterFunctions_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-namespace formatters {
-
-bool JavaStringSummaryProvider(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options);
-
-bool JavaArraySummaryProvider(ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &options);
-
-SyntheticChildrenFrontEnd *
-JavaArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
- lldb::ValueObjectSP valobj_sp);
-
-} // namespace formatters
-} // namespace lldb_private
-
-#endif // liblldb_JavaFormatterFunctions_h_
diff --git a/source/Plugins/Language/Java/JavaLanguage.cpp b/source/Plugins/Language/Java/JavaLanguage.cpp
deleted file mode 100644
index b17862f0b6a2..000000000000
--- a/source/Plugins/Language/Java/JavaLanguage.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-//===-- JavaLanguage.cpp ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-#include <string.h>
-// C++ Includes
-#include <functional>
-#include <mutex>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Threading.h"
-
-// Project includes
-#include "JavaFormatterFunctions.h"
-#include "JavaLanguage.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/JavaASTContext.h"
-#include "lldb/Utility/ConstString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::formatters;
-
-void JavaLanguage::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language",
- CreateInstance);
-}
-
-void JavaLanguage::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString JavaLanguage::GetPluginNameStatic() {
- static ConstString g_name("Java");
- return g_name;
-}
-
-lldb_private::ConstString JavaLanguage::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t JavaLanguage::GetPluginVersion() { return 1; }
-
-Language *JavaLanguage::CreateInstance(lldb::LanguageType language) {
- if (language == eLanguageTypeJava)
- return new JavaLanguage();
- return nullptr;
-}
-
-bool JavaLanguage::IsNilReference(ValueObject &valobj) {
- if (!valobj.GetCompilerType().IsReferenceType())
- return false;
-
- // If we failed to read the value then it is not a nil reference.
- return valobj.GetValueAsUnsigned(UINT64_MAX) == 0;
-}
-
-lldb::TypeCategoryImplSP JavaLanguage::GetFormatters() {
- static llvm::once_flag g_initialize;
- static TypeCategoryImplSP g_category;
-
- llvm::call_once(g_initialize, [this]() -> void {
- DataVisualization::Categories::GetCategory(GetPluginName(), g_category);
- if (g_category) {
- llvm::StringRef array_regexp("^.*\\[\\]&?$");
-
- lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat(
- TypeSummaryImpl::Flags().SetDontShowChildren(true),
- lldb_private::formatters::JavaStringSummaryProvider,
- "java.lang.String summary provider"));
- g_category->GetTypeSummariesContainer()->Add(
- ConstString("java::lang::String"), string_summary_sp);
-
- lldb::TypeSummaryImplSP array_summary_sp(new CXXFunctionSummaryFormat(
- TypeSummaryImpl::Flags().SetDontShowChildren(true),
- lldb_private::formatters::JavaArraySummaryProvider,
- "Java array summary provider"));
- g_category->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(array_regexp)),
- array_summary_sp);
-
-#ifndef LLDB_DISABLE_PYTHON
- AddCXXSynthetic(
- g_category,
- lldb_private::formatters::JavaArraySyntheticFrontEndCreator,
- "Java array synthetic children", ConstString(array_regexp),
- SyntheticChildren::Flags().SetCascades(true), true);
-#endif
- }
- });
- return g_category;
-}
diff --git a/source/Plugins/Language/Java/JavaLanguage.h b/source/Plugins/Language/Java/JavaLanguage.h
deleted file mode 100644
index 5b652502a3d1..000000000000
--- a/source/Plugins/Language/Java/JavaLanguage.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- JavaLanguage.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_JavaLanguage_h_
-#define liblldb_JavaLanguage_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
-// Project includes
-#include "lldb/Target/Language.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class JavaLanguage : public Language {
-public:
- lldb::LanguageType GetLanguageType() const override {
- return lldb::eLanguageTypeJava;
- }
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::Language *CreateInstance(lldb::LanguageType language);
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- bool IsNilReference(ValueObject &valobj) override;
-
- lldb::TypeCategoryImplSP GetFormatters() override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_JavaLanguage_h_
diff --git a/source/Plugins/Language/OCaml/CMakeLists.txt b/source/Plugins/Language/OCaml/CMakeLists.txt
deleted file mode 100644
index e779ae2acd08..000000000000
--- a/source/Plugins/Language/OCaml/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-add_lldb_library(lldbPluginOCamlLanguage PLUGIN
- OCamlLanguage.cpp
-
- LINK_LIBS
- lldbCore
- lldbDataFormatters
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
-)
-
diff --git a/source/Plugins/Language/OCaml/OCamlLanguage.cpp b/source/Plugins/Language/OCaml/OCamlLanguage.cpp
deleted file mode 100644
index ec24a36fe8f3..000000000000
--- a/source/Plugins/Language/OCaml/OCamlLanguage.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- OCamlLanguage.cpp ----------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-#include <string.h>
-// C++ Includes
-#include <functional>
-#include <mutex>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
-// Project includes
-#include "OCamlLanguage.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/DataFormatters/DataVisualization.h"
-#include "lldb/DataFormatters/FormattersHelpers.h"
-#include "lldb/Symbol/OCamlASTContext.h"
-#include "lldb/Utility/ConstString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-void OCamlLanguage::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "OCaml Language",
- CreateInstance);
-}
-
-void OCamlLanguage::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString OCamlLanguage::GetPluginNameStatic() {
- static ConstString g_name("OCaml");
- return g_name;
-}
-
-lldb_private::ConstString OCamlLanguage::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t OCamlLanguage::GetPluginVersion() { return 1; }
-
-Language *OCamlLanguage::CreateInstance(lldb::LanguageType language) {
- if (language == eLanguageTypeOCaml)
- return new OCamlLanguage();
- return nullptr;
-}
-
-bool OCamlLanguage::IsNilReference(ValueObject &valobj) {
- if (!valobj.GetCompilerType().IsReferenceType())
- return false;
-
- // If we failed to read the value then it is not a nil reference.
- return valobj.GetValueAsUnsigned(UINT64_MAX) == 0;
-}
diff --git a/source/Plugins/Language/OCaml/OCamlLanguage.h b/source/Plugins/Language/OCaml/OCamlLanguage.h
deleted file mode 100644
index 21837fe5add4..000000000000
--- a/source/Plugins/Language/OCaml/OCamlLanguage.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-- OCamlLanguage.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_OCamlLanguage_h_
-#define liblldb_OCamlLanguage_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-
-// Other libraries and framework includes
-#include "llvm/ADT/StringRef.h"
-
-// Project includes
-#include "lldb/Target/Language.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class OCamlLanguage : public Language {
-public:
- lldb::LanguageType GetLanguageType() const override {
- return lldb::eLanguageTypeOCaml;
- }
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::Language *CreateInstance(lldb::LanguageType language);
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- bool IsNilReference(ValueObject &valobj) override;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_OCamlLanguage_h_
diff --git a/source/Plugins/Language/ObjC/CF.cpp b/source/Plugins/Language/ObjC/CF.cpp
index 9bb8eeab1d2e..e3dab5a1442d 100644
--- a/source/Plugins/Language/ObjC/CF.cpp
+++ b/source/Plugins/Language/ObjC/CF.cpp
@@ -149,7 +149,7 @@ bool lldb_private::formatters::CFBitVectorSummaryProvider(
}
}
- if (is_type_ok == false)
+ if (!is_type_ok)
return false;
Status error;
diff --git a/source/Plugins/Language/ObjC/CMakeLists.txt b/source/Plugins/Language/ObjC/CMakeLists.txt
index 95ace3a3633a..afb68d4de831 100644
--- a/source/Plugins/Language/ObjC/CMakeLists.txt
+++ b/source/Plugins/Language/ObjC/CMakeLists.txt
@@ -31,6 +31,7 @@ add_lldb_library(lldbPluginObjCLanguage PLUGIN
lldbTarget
lldbUtility
lldbPluginAppleObjCRuntime
+ lldbPluginClangCommon
EXTRA_CXXFLAGS ${EXTRA_CXXFLAGS}
)
diff --git a/source/Plugins/Language/ObjC/Cocoa.cpp b/source/Plugins/Language/ObjC/Cocoa.cpp
index 8f278fc2d513..48085378939e 100644
--- a/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Cocoa.h"
#include "lldb/Core/Mangled.h"
@@ -746,6 +742,59 @@ bool lldb_private::formatters::NSURLSummaryProvider(
return false;
}
+/// Bias value for tagged pointer exponents.
+/// Recommended values:
+/// 0x3e3: encodes all dates between distantPast and distantFuture
+/// except for the range within about 1e-28 second of the reference date.
+/// 0x3ef: encodes all dates for a few million years beyond distantPast and
+/// distantFuture, except within about 1e-25 second of the reference date.
+const int TAGGED_DATE_EXPONENT_BIAS = 0x3ef;
+
+typedef union {
+ struct {
+ uint64_t fraction:52; // unsigned
+ uint64_t exponent:11; // signed
+ uint64_t sign:1;
+ };
+ uint64_t i;
+ double d;
+} DoubleBits;
+typedef union {
+ struct {
+ uint64_t fraction:52; // unsigned
+ uint64_t exponent:7; // signed
+ uint64_t sign:1;
+ uint64_t unused:4; // placeholder for pointer tag bits
+ };
+ uint64_t i;
+} TaggedDoubleBits;
+
+static uint64_t decodeExponent(uint64_t exp) {
+ // Tagged exponent field is 7-bit signed. Sign-extend the value to 64 bits
+ // before performing arithmetic.
+ return llvm::SignExtend64<7>(exp) + TAGGED_DATE_EXPONENT_BIAS;
+}
+
+static uint64_t decodeTaggedTimeInterval(uint64_t encodedTimeInterval) {
+ if (encodedTimeInterval == 0)
+ return 0.0;
+ if (encodedTimeInterval == std::numeric_limits<uint64_t>::max())
+ return (uint64_t)-0.0;
+
+ TaggedDoubleBits encodedBits = {};
+ encodedBits.i = encodedTimeInterval;
+ DoubleBits decodedBits;
+
+ // Sign and fraction are represented exactly.
+ // Exponent is encoded.
+ assert(encodedBits.unused == 0);
+ decodedBits.sign = encodedBits.sign;
+ decodedBits.fraction = encodedBits.fraction;
+ decodedBits.exponent = decodeExponent(encodedBits.exponent);
+
+ return decodedBits.d;
+}
+
bool lldb_private::formatters::NSDateSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
ProcessSP process_sp = valobj.GetProcessSP();
@@ -785,9 +834,9 @@ bool lldb_private::formatters::NSDateSummaryProvider(
if (class_name.IsEmpty())
return false;
+ uint64_t info_bits = 0, value_bits = 0;
if ((class_name == g_NSDate) || (class_name == g___NSDate) ||
(class_name == g___NSTaggedDate)) {
- uint64_t info_bits = 0, value_bits = 0;
if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) {
date_value_bits = ((value_bits << 8) | (info_bits << 4));
memcpy(&date_value, &date_value_bits, sizeof(date_value_bits));
@@ -817,6 +866,14 @@ bool lldb_private::formatters::NSDateSummaryProvider(
stream.Printf("0001-12-30 00:00:00 +0000");
return true;
}
+
+ // Accomodate for the __NSTaggedDate format introduced in Foundation 1600.
+ if (class_name == g___NSTaggedDate) {
+ auto *runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(process_sp->GetObjCLanguageRuntime());
+ if (runtime && runtime->GetFoundationVersion() >= 1600)
+ date_value = decodeTaggedTimeInterval(value_bits << 4);
+ }
+
// this snippet of code assumes that time_t == seconds since Jan-1-1970 this
// is generally true and POSIXly happy, but might break if a library vendor
// decides to get creative
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index f6d159201951..6c110da9ecc2 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
-// Project includes
#include "Cocoa.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
@@ -218,6 +214,25 @@ namespace Foundation1437 {
}
+namespace CallStackArray {
+struct DataDescriptor_32 {
+ uint32_t _data;
+ uint32_t _used;
+ uint32_t _offset;
+ const uint32_t _size = 0;
+};
+
+struct DataDescriptor_64 {
+ uint64_t _data;
+ uint64_t _used;
+ uint64_t _offset;
+ const uint64_t _size = 0;
+};
+
+using NSCallStackArraySyntheticFrontEnd =
+ GenericNSArrayMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+} // namespace CallStackArray
+
template <typename D32, typename D64, bool Inline>
class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
@@ -368,6 +383,7 @@ bool lldb_private::formatters::NSArraySummaryProvider(
static const ConstString g_NSArrayCF("__NSCFArray");
static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
+ static const ConstString g_NSCallStackArray("_NSCallStackArray");
if (class_name.IsEmpty())
return false;
@@ -417,7 +433,9 @@ bool lldb_private::formatters::NSArraySummaryProvider(
value = 0;
} else if (class_name == g_NSArray1) {
value = 1;
- } else if (class_name == g_NSArrayCF) {
+ } else if (class_name == g_NSArrayCF || class_name == g_NSCallStackArray) {
+ // __NSCFArray and _NSCallStackArray store the number of elements as a
+ // pointer-sized value at offset `2 * ptr_size`.
Status error;
value = process_sp->ReadUnsignedIntegerFromMemory(
valobj_addr + 2 * ptr_size, ptr_size, 0, error);
@@ -817,6 +835,7 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
static const ConstString g_NSArray1("__NSSingleObjectArrayI");
static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
+ static const ConstString g_NSCallStackArray("_NSCallStackArray");
if (class_name.IsEmpty())
return nullptr;
@@ -846,6 +865,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator(
return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp));
else
return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp));
+ } else if (class_name == g_NSCallStackArray) {
+ return (new CallStackArray::NSCallStackArraySyntheticFrontEnd(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 5be051b46bd6..9a7fc2bd97cb 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -7,14 +7,10 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
#include "clang/AST/DeclCXX.h"
-// Project includes
#include "NSDictionary.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
diff --git a/source/Plugins/Language/ObjC/NSError.cpp b/source/Plugins/Language/ObjC/NSError.cpp
index 77721e2db326..975bda5179f2 100644
--- a/source/Plugins/Language/ObjC/NSError.cpp
+++ b/source/Plugins/Language/ObjC/NSError.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/DeclCXX.h"
-// Project includes
#include "Cocoa.h"
#include "lldb/Core/ValueObject.h"
diff --git a/source/Plugins/Language/ObjC/NSException.cpp b/source/Plugins/Language/ObjC/NSException.cpp
index c6970efae4d3..2404ef9d1003 100644
--- a/source/Plugins/Language/ObjC/NSException.cpp
+++ b/source/Plugins/Language/ObjC/NSException.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/DeclCXX.h"
-// Project includes
#include "Cocoa.h"
#include "lldb/Core/ValueObject.h"
@@ -33,52 +29,78 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
-bool lldb_private::formatters::NSException_SummaryProvider(
- ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp,
+ ValueObjectSP *reason_sp, ValueObjectSP *userinfo_sp,
+ ValueObjectSP *reserved_sp) {
ProcessSP process_sp(valobj.GetProcessSP());
if (!process_sp)
return false;
- lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS;
+ lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
CompilerType valobj_type(valobj.GetCompilerType());
Flags type_flags(valobj_type.GetTypeInfo());
if (type_flags.AllClear(eTypeHasValue)) {
if (valobj.IsBaseClass() && valobj.GetParent())
- ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- } else
- ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ ptr = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ } else {
+ ptr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ }
- if (ptr_value == LLDB_INVALID_ADDRESS)
+ if (ptr == LLDB_INVALID_ADDRESS)
return false;
size_t ptr_size = process_sp->GetAddressByteSize();
- lldb::addr_t name_location = ptr_value + 1 * ptr_size;
- lldb::addr_t reason_location = ptr_value + 2 * ptr_size;
Status error;
- lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error);
+ auto name = process_sp->ReadPointerFromMemory(ptr + 1 * ptr_size, error);
if (error.Fail() || name == LLDB_INVALID_ADDRESS)
return false;
-
- lldb::addr_t reason =
- process_sp->ReadPointerFromMemory(reason_location, error);
+ auto reason = process_sp->ReadPointerFromMemory(ptr + 2 * ptr_size, error);
if (error.Fail() || reason == LLDB_INVALID_ADDRESS)
return false;
+ auto userinfo = process_sp->ReadPointerFromMemory(ptr + 3 * ptr_size, error);
+ if (error.Fail() || userinfo == LLDB_INVALID_ADDRESS)
+ return false;
+ auto reserved = process_sp->ReadPointerFromMemory(ptr + 4 * ptr_size, error);
+ if (error.Fail() || reserved == LLDB_INVALID_ADDRESS)
+ return false;
InferiorSizedWord name_isw(name, *process_sp);
InferiorSizedWord reason_isw(reason, *process_sp);
+ InferiorSizedWord userinfo_isw(userinfo, *process_sp);
+ InferiorSizedWord reserved_isw(reserved, *process_sp);
CompilerType voidstar = process_sp->GetTarget()
.GetScratchClangASTContext()
->GetBasicType(lldb::eBasicTypeVoid)
.GetPointerType();
- ValueObjectSP name_sp = ValueObject::CreateValueObjectFromData(
- "name_str", name_isw.GetAsData(process_sp->GetByteOrder()),
- valobj.GetExecutionContextRef(), voidstar);
- ValueObjectSP reason_sp = ValueObject::CreateValueObjectFromData(
- "reason_str", reason_isw.GetAsData(process_sp->GetByteOrder()),
- valobj.GetExecutionContextRef(), voidstar);
+ if (name_sp)
+ *name_sp = ValueObject::CreateValueObjectFromData(
+ "name", name_isw.GetAsData(process_sp->GetByteOrder()),
+ valobj.GetExecutionContextRef(), voidstar);
+ if (reason_sp)
+ *reason_sp = ValueObject::CreateValueObjectFromData(
+ "reason", reason_isw.GetAsData(process_sp->GetByteOrder()),
+ valobj.GetExecutionContextRef(), voidstar);
+ if (userinfo_sp)
+ *userinfo_sp = ValueObject::CreateValueObjectFromData(
+ "userInfo", userinfo_isw.GetAsData(process_sp->GetByteOrder()),
+ valobj.GetExecutionContextRef(), voidstar);
+ if (reserved_sp)
+ *reserved_sp = ValueObject::CreateValueObjectFromData(
+ "reserved", reserved_isw.GetAsData(process_sp->GetByteOrder()),
+ valobj.GetExecutionContextRef(), voidstar);
+
+ return true;
+}
+
+bool lldb_private::formatters::NSException_SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ lldb::ValueObjectSP name_sp;
+ lldb::ValueObjectSP reason_sp;
+ if (!ExtractFields(valobj, &name_sp, &reason_sp, nullptr, nullptr))
+ return false;
if (!name_sp || !reason_sp)
return false;
@@ -101,83 +123,55 @@ public:
: SyntheticChildrenFrontEnd(*valobj_sp) {}
~NSExceptionSyntheticFrontEnd() override = default;
- // no need to delete m_child_ptr - it's kept alive by the cluster manager on
- // our behalf
size_t CalculateNumChildren() override {
- if (m_child_ptr)
- return 1;
- if (m_child_sp)
- return 1;
- return 0;
+ return 4;
}
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
- if (idx != 0)
- return lldb::ValueObjectSP();
-
- if (m_child_ptr)
- return m_child_ptr->GetSP();
- return m_child_sp;
+ switch (idx) {
+ case 0: return m_name_sp;
+ case 1: return m_reason_sp;
+ case 2: return m_userinfo_sp;
+ case 3: return m_reserved_sp;
+ }
+ return lldb::ValueObjectSP();
}
bool Update() override {
- m_child_ptr = nullptr;
- m_child_sp.reset();
-
- ProcessSP process_sp(m_backend.GetProcessSP());
- if (!process_sp)
- return false;
-
- lldb::addr_t userinfo_location = LLDB_INVALID_ADDRESS;
-
- CompilerType valobj_type(m_backend.GetCompilerType());
- Flags type_flags(valobj_type.GetTypeInfo());
- if (type_flags.AllClear(eTypeHasValue)) {
- if (m_backend.IsBaseClass() && m_backend.GetParent())
- userinfo_location =
- m_backend.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- } else
- userinfo_location = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
-
- if (userinfo_location == LLDB_INVALID_ADDRESS)
- return false;
-
- size_t ptr_size = process_sp->GetAddressByteSize();
-
- userinfo_location += 3 * ptr_size;
- Status error;
- lldb::addr_t userinfo =
- process_sp->ReadPointerFromMemory(userinfo_location, error);
- if (userinfo == LLDB_INVALID_ADDRESS || error.Fail())
- return false;
- InferiorSizedWord isw(userinfo, *process_sp);
- m_child_sp = CreateValueObjectFromData(
- "userInfo", isw.GetAsData(process_sp->GetByteOrder()),
- m_backend.GetExecutionContextRef(),
- process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(
- lldb::eBasicTypeObjCID));
- return false;
+ m_name_sp.reset();
+ m_reason_sp.reset();
+ m_userinfo_sp.reset();
+ m_reserved_sp.reset();
+
+ return ExtractFields(m_backend, &m_name_sp, &m_reason_sp, &m_userinfo_sp,
+ &m_reserved_sp);
}
bool MightHaveChildren() override { return true; }
size_t GetIndexOfChildWithName(const ConstString &name) override {
+ // NSException has 4 members:
+ // NSString *name;
+ // NSString *reason;
+ // NSDictionary *userInfo;
+ // id reserved;
+ static ConstString g___name("name");
+ static ConstString g___reason("reason");
static ConstString g___userInfo("userInfo");
- if (name == g___userInfo)
- return 0;
+ static ConstString g___reserved("reserved");
+ if (name == g___name) return 0;
+ if (name == g___reason) return 1;
+ if (name == g___userInfo) return 2;
+ if (name == g___reserved) return 3;
return UINT32_MAX;
}
private:
- // the child here can be "real" (i.e. an actual child of the root) or
- // synthetized from raw memory if the former, I need to store a plain pointer
- // to it - or else a loop of references will cause this entire hierarchy of
- // values to leak if the latter, then I need to store a SharedPointer to it -
- // so that it only goes away when everyone else in the cluster goes away oh
- // joy!
- ValueObject *m_child_ptr;
- ValueObjectSP m_child_sp;
+ ValueObjectSP m_name_sp;
+ ValueObjectSP m_reason_sp;
+ ValueObjectSP m_userinfo_sp;
+ ValueObjectSP m_reserved_sp;
};
SyntheticChildrenFrontEnd *
diff --git a/source/Plugins/Language/ObjC/NSIndexPath.cpp b/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 9533e96004a5..41df9abb3eb2 100644
--- a/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Cocoa.h"
#include "lldb/Core/ValueObject.h"
@@ -130,11 +126,7 @@ public:
return false;
}
- bool MightHaveChildren() override {
- if (m_impl.m_mode == Mode::Invalid)
- return false;
- return true;
- }
+ bool MightHaveChildren() override { return m_impl.m_mode != Mode::Invalid; }
size_t GetIndexOfChildWithName(const ConstString &name) override {
const char *item_name = name.GetCString();
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 2da4bc034f32..7e03d7574af0 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "NSSet.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
diff --git a/source/Plugins/Language/ObjC/NSString.cpp b/source/Plugins/Language/ObjC/NSString.cpp
index 0b12edb53d7a..f882b2adc260 100644
--- a/source/Plugins/Language/ObjC/NSString.cpp
+++ b/source/Plugins/Language/ObjC/NSString.cpp
@@ -225,10 +225,10 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetBinaryZeroIsTerminator(!has_explicit_length);
options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
@@ -245,10 +245,10 @@ bool lldb_private::formatters::NSStringSummaryProvider(
options.SetStream(&stream);
options.SetQuote('"');
options.SetSourceSize(explicit_length);
- options.SetNeedsZeroTermination(has_explicit_length == false);
+ options.SetNeedsZeroTermination(!has_explicit_length);
options.SetIgnoreMaxLength(summary_options.GetCapping() ==
TypeSummaryCapping::eTypeSummaryUncapped);
- options.SetBinaryZeroIsTerminator(has_explicit_length == false);
+ options.SetBinaryZeroIsTerminator(!has_explicit_length);
options.SetLanguage(summary_options.GetLanguage());
return StringPrinter::ReadStringAndDumpToStream<
StringPrinter::StringElementType::UTF16>(options);
@@ -260,10 +260,7 @@ bool lldb_private::formatters::NSStringSummaryProvider(
Status error;
explicit_length =
process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error);
- if (error.Fail() || explicit_length == 0)
- has_explicit_length = false;
- else
- has_explicit_length = true;
+ has_explicit_length = !(error.Fail() || explicit_length == 0);
location++;
}
options.SetLocation(location);
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
index 47874b3be8fd..0598d69f6ebb 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.cpp
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
-// Project includes
#include "ObjCLanguage.h"
#include "lldb/Core/PluginManager.h"
@@ -413,6 +409,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
"NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
AddCXXSummary(
objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
+ "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags);
+ AddCXXSummary(
+ objc_category_sp, lldb_private::formatters::NSArraySummaryProvider,
"NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
AddCXXSummary(objc_category_sp,
lldb_private::formatters::NSArraySummaryProvider,
@@ -532,6 +531,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) {
ScriptedSyntheticChildren::Flags());
AddCXXSynthetic(objc_category_sp,
lldb_private::formatters::NSArraySyntheticFrontEndCreator,
+ "NSArray synthetic children", ConstString("_NSCallStackArray"),
+ ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(objc_category_sp,
+ lldb_private::formatters::NSArraySyntheticFrontEndCreator,
"NSArray synthetic children",
ConstString("CFMutableArrayRef"),
ScriptedSyntheticChildren::Flags());
@@ -1102,3 +1105,12 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) {
bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0;
return canReadValue && isZero;
}
+
+bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
+ const auto suffixes = {".h", ".m", ".M"};
+ for (auto suffix : suffixes) {
+ if (file_path.endswith_lower(suffix))
+ return true;
+ }
+ return false;
+}
diff --git a/source/Plugins/Language/ObjC/ObjCLanguage.h b/source/Plugins/Language/ObjC/ObjCLanguage.h
index 9782c5da0d67..114f9323de02 100644
--- a/source/Plugins/Language/ObjC/ObjCLanguage.h
+++ b/source/Plugins/Language/ObjC/ObjCLanguage.h
@@ -10,13 +10,10 @@
#ifndef liblldb_ObjCLanguage_h_
#define liblldb_ObjCLanguage_h_
-// C Includes
-// C++ Includes
#include <cstring>
#include <vector>
-// Other libraries and framework includes
-// Project includes
+#include "Plugins/Language/ClangCommon/ClangHighlighter.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
@@ -24,6 +21,8 @@
namespace lldb_private {
class ObjCLanguage : public Language {
+ ClangHighlighter m_highlighter;
+
public:
class MethodName {
public:
@@ -121,6 +120,10 @@ public:
bool IsNilReference(ValueObject &valobj) override;
+ bool IsSourceFile(llvm::StringRef file_path) const override;
+
+ const Highlighter *GetHighlighter() const override { return &m_highlighter; }
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt b/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt
index 75df9794d75d..1aa5cc1ed488 100644
--- a/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt
+++ b/source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt
@@ -1,7 +1,8 @@
add_lldb_library(lldbPluginObjCPlusPlusLanguage PLUGIN
ObjCPlusPlusLanguage.cpp
-
+
LINK_LIBS
lldbCore
lldbTarget
+ lldbPluginClangCommon
)
diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
index bfc22c9ee650..5e6d86e05318 100644
--- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp
@@ -16,6 +16,15 @@
using namespace lldb;
using namespace lldb_private;
+bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const {
+ const auto suffixes = {".h", ".mm"};
+ for (auto suffix : suffixes) {
+ if (file_path.endswith_lower(suffix))
+ return true;
+ }
+ return false;
+}
+
void ObjCPlusPlusLanguage::Initialize() {
PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C++ Language",
CreateInstance);
diff --git a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
index 588b52215c10..b64f0f81e001 100644
--- a/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
+++ b/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h
@@ -10,16 +10,15 @@
#ifndef liblldb_ObjCPlusPlusLanguage_h_
#define liblldb_ObjCPlusPlusLanguage_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+#include "Plugins/Language/ClangCommon/ClangHighlighter.h"
#include "lldb/Target/Language.h"
#include "lldb/lldb-private.h"
namespace lldb_private {
class ObjCPlusPlusLanguage : public Language {
+ ClangHighlighter m_highlighter;
+
public:
ObjCPlusPlusLanguage() = default;
@@ -29,6 +28,10 @@ public:
return lldb::eLanguageTypeObjC_plus_plus;
}
+ bool IsSourceFile(llvm::StringRef file_path) const override;
+
+ const Highlighter *GetHighlighter() const override { return &m_highlighter; }
+
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/source/Plugins/LanguageRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/CMakeLists.txt
index 2cf579212ec1..c62791445a9a 100644
--- a/source/Plugins/LanguageRuntime/CMakeLists.txt
+++ b/source/Plugins/LanguageRuntime/CMakeLists.txt
@@ -1,5 +1,3 @@
add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
-add_subdirectory(Go)
-add_subdirectory(Java)
add_subdirectory(RenderScript)
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index fc661bbbf2c9..49a3d40d7b37 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -14,9 +14,11 @@
#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -32,6 +34,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include <vector>
@@ -98,7 +101,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
llvm::DenseSet<SymbolFile *> searched_symbol_files;
if (sc.module_sp) {
num_matches = sc.module_sp->FindTypes(
- sc, ConstString(lookup_name), exact_match, 1,
+ ConstString(lookup_name), exact_match, 1,
searched_symbol_files, class_types);
}
@@ -106,7 +109,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
// list in the target and get as many unique matches as possible
if (num_matches == 0) {
num_matches = target.GetImages().FindTypes(
- sc, ConstString(lookup_name), exact_match, UINT32_MAX,
+ nullptr, ConstString(lookup_name), exact_match, UINT32_MAX,
searched_symbol_files, class_types);
}
@@ -204,71 +207,71 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(
// Only a pointer or reference type can have a different dynamic and static
// type:
- if (CouldHaveDynamicValue(in_value)) {
- // First job, pull out the address at 0 offset from the object.
- AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
- if (original_ptr == LLDB_INVALID_ADDRESS)
- return false;
+ if (!CouldHaveDynamicValue(in_value))
+ return false;
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+ // First job, pull out the address at 0 offset from the object.
+ AddressType address_type;
+ lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
+ if (original_ptr == LLDB_INVALID_ADDRESS)
+ return false;
- Process *process = exe_ctx.GetProcessPtr();
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
- if (process == nullptr)
- return false;
+ Process *process = exe_ctx.GetProcessPtr();
- Status error;
- const lldb::addr_t vtable_address_point =
- process->ReadPointerFromMemory(original_ptr, error);
+ if (process == nullptr)
+ return false;
- if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) {
- return false;
- }
+ Status error;
+ const lldb::addr_t vtable_address_point =
+ process->ReadPointerFromMemory(original_ptr, error);
- class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr,
- vtable_address_point);
-
- if (class_type_or_name) {
- TypeSP type_sp = class_type_or_name.GetTypeSP();
- // There can only be one type with a given name, so we've just found
- // duplicate definitions, and this one will do as well as any other. We
- // don't consider something to have a dynamic type if it is the same as
- // the static type. So compare against the value we were handed.
- if (type_sp) {
- if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(),
- type_sp->GetForwardCompilerType())) {
- // The dynamic type we found was the same type, so we don't have a
- // dynamic type here...
- return false;
- }
+ if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
+ return false;
- // The offset_to_top is two pointers above the vtable pointer.
- const uint32_t addr_byte_size = process->GetAddressByteSize();
- const lldb::addr_t offset_to_top_location =
- vtable_address_point - 2 * addr_byte_size;
- // Watch for underflow, offset_to_top_location should be less than
- // vtable_address_point
- if (offset_to_top_location >= vtable_address_point)
- return false;
- const int64_t offset_to_top = process->ReadSignedIntegerFromMemory(
- offset_to_top_location, addr_byte_size, INT64_MIN, error);
-
- if (offset_to_top == INT64_MIN)
- return false;
- // So the dynamic type is a value that starts at offset_to_top above
- // the original address.
- lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
- if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(
- dynamic_addr, dynamic_address)) {
- dynamic_address.SetRawAddress(dynamic_addr);
- }
- return true;
- }
- }
+ class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr,
+ vtable_address_point);
+
+ if (!class_type_or_name)
+ return false;
+
+ TypeSP type_sp = class_type_or_name.GetTypeSP();
+ // There can only be one type with a given name, so we've just found
+ // duplicate definitions, and this one will do as well as any other. We
+ // don't consider something to have a dynamic type if it is the same as
+ // the static type. So compare against the value we were handed.
+ if (!type_sp)
+ return true;
+
+ if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(),
+ type_sp->GetForwardCompilerType())) {
+ // The dynamic type we found was the same type, so we don't have a
+ // dynamic type here...
+ return false;
}
- return class_type_or_name.IsEmpty() == false;
+ // The offset_to_top is two pointers above the vtable pointer.
+ const uint32_t addr_byte_size = process->GetAddressByteSize();
+ const lldb::addr_t offset_to_top_location =
+ vtable_address_point - 2 * addr_byte_size;
+ // Watch for underflow, offset_to_top_location should be less than
+ // vtable_address_point
+ if (offset_to_top_location >= vtable_address_point)
+ return false;
+ const int64_t offset_to_top = process->ReadSignedIntegerFromMemory(
+ offset_to_top_location, addr_byte_size, INT64_MIN, error);
+
+ if (offset_to_top == INT64_MIN)
+ return false;
+ // So the dynamic type is a value that starts at offset_to_top above
+ // the original address.
+ lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
+ if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(
+ dynamic_addr, dynamic_address)) {
+ dynamic_address.SetRawAddress(dynamic_addr);
+ }
+ return true;
}
TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType(
@@ -309,10 +312,7 @@ bool ItaniumABILanguageRuntime::IsVTableName(const char *name) {
return false;
// Can we maybe ask Clang about this?
- if (strstr(name, "_vptr$") == name)
- return true;
- else
- return false;
+ return strstr(name, "_vptr$") == name;
}
//------------------------------------------------------------------
@@ -483,8 +483,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() {
// Limit the number of modules that are searched for these breakpoints for
// Apple binaries.
FileSpecList filter_modules;
- filter_modules.Append(FileSpec("libc++abi.dylib", false));
- filter_modules.Append(FileSpec("libSystem.B.dylib", false));
+ filter_modules.Append(FileSpec("libc++abi.dylib"));
+ filter_modules.Append(FileSpec("libSystem.B.dylib"));
return target.GetSearchFilterForModuleList(&filter_modules);
} else {
return LanguageRuntime::CreateExceptionSearchFilter();
@@ -552,6 +552,64 @@ bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop(
break_site_id, m_cxx_exception_bp_sp->GetID());
}
+ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread(
+ ThreadSP thread_sp) {
+ if (!thread_sp->SafeToCallFunctions())
+ return {};
+
+ ClangASTContext *clang_ast_context =
+ m_process->GetTarget().GetScratchClangASTContext();
+ CompilerType voidstar =
+ clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+
+ DiagnosticManager diagnostics;
+ ExecutionContext exe_ctx;
+ EvaluateExpressionOptions options;
+
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetStopOthers(true);
+ options.SetTimeout(std::chrono::milliseconds(500));
+ options.SetTryAllThreads(false);
+ thread_sp->CalculateExecutionContext(exe_ctx);
+
+ const ModuleList &modules = m_process->GetTarget().GetImages();
+ SymbolContextList contexts;
+ SymbolContext context;
+
+ modules.FindSymbolsWithNameAndType(
+ ConstString("__cxa_current_exception_type"), eSymbolTypeCode, contexts);
+ contexts.GetContextAtIndex(0, context);
+ Address addr = context.symbol->GetAddress();
+
+ Status error;
+ FunctionCaller *function_caller =
+ m_process->GetTarget().GetFunctionCallerForLanguage(
+ eLanguageTypeC, voidstar, addr, ValueList(), "caller", error);
+
+ ExpressionResults func_call_ret;
+ Value results;
+ func_call_ret = function_caller->ExecuteFunction(exe_ctx, nullptr, options,
+ diagnostics, results);
+ if (func_call_ret != eExpressionCompleted || !error.Success()) {
+ return ValueObjectSP();
+ }
+
+ size_t ptr_size = m_process->GetAddressByteSize();
+ addr_t result_ptr = results.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ addr_t exception_addr =
+ m_process->ReadPointerFromMemory(result_ptr - ptr_size, error);
+
+ lldb_private::formatters::InferiorSizedWord exception_isw(exception_addr,
+ *m_process);
+ ValueObjectSP exception = ValueObject::CreateValueObjectFromData(
+ "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx,
+ voidstar);
+ exception = exception->GetDynamicValue(eDynamicDontRunTarget);
+
+ return exception;
+}
+
TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo(
const lldb_private::Address &vtable_addr) {
std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index 480c32691c8b..abed3706c6b8 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -10,14 +10,10 @@
#ifndef liblldb_ItaniumABILanguageRuntime_h_
#define liblldb_ItaniumABILanguageRuntime_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/Type.h"
@@ -69,6 +65,9 @@ public:
bool throw_bp) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ lldb::ValueObjectSP GetExceptionObjectForThread(
+ lldb::ThreadSP thread_sp) override;
//------------------------------------------------------------------
// PluginInterface protocol
diff --git a/source/Plugins/LanguageRuntime/Go/CMakeLists.txt b/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
index 16756d5c985a..62418def58f6 100644
--- a/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
+++ b/source/Plugins/LanguageRuntime/Go/CMakeLists.txt
@@ -1,8 +1,6 @@
set(LLVM_NO_RTTI 1)
add_lldb_library(lldbPluginLanguageRuntimeGo PLUGIN
- GoLanguageRuntime.cpp
-
LINK_LIBS
lldbBreakpoint
lldbCore
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
deleted file mode 100644
index 6670f89dde5f..000000000000
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
+++ /dev/null
@@ -1,215 +0,0 @@
-//===-- GoLanguageRuntime.cpp --------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "GoLanguageRuntime.h"
-
-#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Core/ValueObjectMemory.h"
-#include "lldb/Symbol/GoASTContext.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/TypeList.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "llvm/ADT/Twine.h"
-
-#include <vector>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-ValueObjectSP GetChild(ValueObject &obj, const char *name,
- bool dereference = true) {
- ConstString name_const_str(name);
- ValueObjectSP result = obj.GetChildMemberWithName(name_const_str, true);
- if (dereference && result && result->IsPointerType()) {
- Status err;
- result = result->Dereference(err);
- if (err.Fail())
- result.reset();
- }
- return result;
-}
-
-ConstString ReadString(ValueObject &str, Process *process) {
- ConstString result;
- ValueObjectSP data = GetChild(str, "str", false);
- ValueObjectSP len = GetChild(str, "len");
- if (len && data) {
- Status err;
- lldb::addr_t addr = data->GetPointerValue();
- if (addr == LLDB_INVALID_ADDRESS)
- return result;
- uint64_t byte_size = len->GetValueAsUnsigned(0);
- char *buf = new char[byte_size + 1];
- buf[byte_size] = 0;
- size_t bytes_read = process->ReadMemory(addr, buf, byte_size, err);
- if (!(err.Fail() || bytes_read != byte_size))
- result = ConstString(buf, bytes_read);
- delete[] buf;
- }
- return result;
-}
-
-ConstString ReadTypeName(ValueObjectSP type, Process *process) {
- if (ValueObjectSP uncommon = GetChild(*type, "x")) {
- ValueObjectSP name = GetChild(*uncommon, "name");
- ValueObjectSP package = GetChild(*uncommon, "pkgpath");
- if (name && name->GetPointerValue() != 0 && package &&
- package->GetPointerValue() != 0) {
- ConstString package_const_str = ReadString(*package, process);
- ConstString name_const_str = ReadString(*name, process);
- if (package_const_str.GetLength() == 0)
- return name_const_str;
- return ConstString((package_const_str.GetStringRef() + "." +
- name_const_str.GetStringRef())
- .str());
- }
- }
- ValueObjectSP name = GetChild(*type, "_string");
- if (name)
- return ReadString(*name, process);
- return ConstString("");
-}
-
-CompilerType LookupRuntimeType(ValueObjectSP type, ExecutionContext *exe_ctx,
- bool *is_direct) {
- uint8_t kind = GetChild(*type, "kind")->GetValueAsUnsigned(0);
- *is_direct = GoASTContext::IsDirectIface(kind);
- if (GoASTContext::IsPointerKind(kind)) {
- CompilerType type_ptr = type->GetCompilerType().GetPointerType();
- Status err;
- ValueObjectSP elem =
- type->CreateValueObjectFromAddress("elem", type->GetAddressOf() +
- type->GetByteSize(),
- *exe_ctx, type_ptr)
- ->Dereference(err);
- if (err.Fail())
- return CompilerType();
- bool tmp_direct;
- return LookupRuntimeType(elem, exe_ctx, &tmp_direct).GetPointerType();
- }
- Target *target = exe_ctx->GetTargetPtr();
- Process *process = exe_ctx->GetProcessPtr();
-
- ConstString const_typename = ReadTypeName(type, process);
- if (const_typename.GetLength() == 0)
- return CompilerType();
-
- SymbolContext sc;
- TypeList type_list;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- uint32_t num_matches = target->GetImages().FindTypes(
- sc, const_typename, false, 2, searched_symbol_files, type_list);
- if (num_matches > 0) {
- return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
- }
- return CompilerType();
-}
-}
-
-bool GoLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
- return GoASTContext::IsGoInterface(in_value.GetCompilerType());
-}
-
-bool GoLanguageRuntime::GetDynamicTypeAndAddress(
- ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type) {
- value_type = Value::eValueTypeScalar;
- class_type_or_name.Clear();
- if (CouldHaveDynamicValue(in_value)) {
- Status err;
- ValueObjectSP iface = in_value.GetStaticValue();
- ValueObjectSP data_sp = GetChild(*iface, "data", false);
- if (!data_sp)
- return false;
-
- if (ValueObjectSP tab = GetChild(*iface, "tab"))
- iface = tab;
- ValueObjectSP type = GetChild(*iface, "_type");
- if (!type) {
- return false;
- }
-
- bool direct;
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
- CompilerType final_type = LookupRuntimeType(type, &exe_ctx, &direct);
- if (!final_type)
- return false;
- if (direct) {
- class_type_or_name.SetCompilerType(final_type);
- } else {
- // TODO: implement reference types or fix caller to support dynamic types
- // that aren't pointers
- // so we don't have to introduce this extra pointer.
- class_type_or_name.SetCompilerType(final_type.GetPointerType());
- }
-
- dynamic_address.SetLoadAddress(data_sp->GetPointerValue(),
- exe_ctx.GetTargetPtr());
-
- return true;
- }
- return false;
-}
-
-TypeAndOrName
-GoLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
- ValueObject &static_value) {
- return type_and_or_name;
-}
-
-//------------------------------------------------------------------
-// Static Functions
-//------------------------------------------------------------------
-LanguageRuntime *
-GoLanguageRuntime::CreateInstance(Process *process,
- lldb::LanguageType language) {
- if (language == eLanguageTypeGo)
- return new GoLanguageRuntime(process);
- else
- return NULL;
-}
-
-void GoLanguageRuntime::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language Runtime",
- CreateInstance);
-}
-
-void GoLanguageRuntime::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString GoLanguageRuntime::GetPluginNameStatic() {
- static ConstString g_name("golang");
- return g_name;
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-lldb_private::ConstString GoLanguageRuntime::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t GoLanguageRuntime::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
deleted file mode 100644
index 9c2ee15cff65..000000000000
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//===-- GoLanguageRuntime.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_GoLanguageRuntime_h_
-#define liblldb_GoLanguageRuntime_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Breakpoint/BreakpointResolver.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class GoLanguageRuntime : public lldb_private::LanguageRuntime {
-public:
- ~GoLanguageRuntime() override = default;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::LanguageRuntime *
- CreateInstance(Process *process, lldb::LanguageType language);
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- lldb::LanguageType GetLanguageType() const override {
- return lldb::eLanguageTypeGo;
- }
-
- bool GetObjectDescription(Stream &str, ValueObject &object) override {
- // TODO(ribrdb): Maybe call String() method?
- return false;
- }
-
- bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) override {
- return false;
- }
-
- bool GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
- bool CouldHaveDynamicValue(ValueObject &in_value) override;
-
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp) override {
- return lldb::BreakpointResolverSP();
- }
-
- TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
- ValueObject &static_value) override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
-private:
- GoLanguageRuntime(Process *process)
- : lldb_private::LanguageRuntime(process) {
- } // Call CreateInstance instead.
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_GoLanguageRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/Java/CMakeLists.txt b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
deleted file mode 100644
index ec87718752e7..000000000000
--- a/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginLanguageRuntimeJava PLUGIN
- JavaLanguageRuntime.cpp
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
deleted file mode 100644
index 36c30a99ff87..000000000000
--- a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-//===-- JavaLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "JavaLanguageRuntime.h"
-
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Symbol/JavaASTContext.h"
-#include "lldb/Symbol/Symbol.h"
-#include "lldb/Symbol/SymbolContext.h"
-#include "lldb/Symbol/SymbolFile.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/TypeList.h"
-#include "lldb/Target/SectionLoadList.h"
-#include "lldb/Target/Target.h"
-#include "llvm/ADT/StringRef.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-JavaLanguageRuntime::JavaLanguageRuntime(Process *process)
- : LanguageRuntime(process) {}
-
-LanguageRuntime *
-JavaLanguageRuntime::CreateInstance(Process *process,
- lldb::LanguageType language) {
- if (language == eLanguageTypeJava)
- return new JavaLanguageRuntime(process);
- return nullptr;
-}
-
-void JavaLanguageRuntime::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime",
- CreateInstance);
-}
-
-void JavaLanguageRuntime::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-lldb_private::ConstString JavaLanguageRuntime::GetPluginNameStatic() {
- static ConstString g_name("java");
- return g_name;
-}
-
-lldb_private::ConstString JavaLanguageRuntime::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t JavaLanguageRuntime::GetPluginVersion() { return 1; }
-
-bool JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
- return true;
-}
-
-static ConstString GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target,
- ValueObject &in_value) {
- SymbolContext sc;
- TypeList class_types;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- size_t num_matches = target->GetImages().FindTypes(
- sc, ConstString("Object"),
- true, // name_is_fully_qualified
- UINT32_MAX, searched_symbol_files, class_types);
- for (size_t i = 0; i < num_matches; ++i) {
- TypeSP type_sp = class_types.GetTypeAtIndex(i);
- CompilerType compiler_type = type_sp->GetFullCompilerType();
-
- if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava ||
- compiler_type.GetTypeName() != ConstString("java::lang::Object"))
- continue;
-
- if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) {
- uint64_t type_id = JavaASTContext::CalculateDynamicTypeId(
- exe_ctx, compiler_type, in_value);
- if (type_id != UINT64_MAX) {
- char id[32];
- snprintf(id, sizeof(id), "0x%" PRIX64, type_id);
- return ConstString(id);
- }
- }
- }
- return ConstString();
-}
-
-bool JavaLanguageRuntime::GetDynamicTypeAndAddress(
- ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &dynamic_address,
- Value::ValueType &value_type) {
- class_type_or_name.Clear();
-
- // null references don't have a dynamic type
- if (in_value.IsNilReference())
- return false;
-
- ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
- if (!target)
- return false;
-
- ConstString linkage_name;
- CompilerType in_type = in_value.GetCompilerType();
- if (in_type.IsPossibleDynamicType(nullptr, false, false))
- linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value);
- else
- linkage_name = JavaASTContext::GetLinkageName(in_type);
-
- if (!linkage_name)
- return false;
-
- class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName());
-
- SymbolContext sc;
- TypeList class_types;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- size_t num_matches = target->GetImages().FindTypes(
- sc, linkage_name,
- true, // name_is_fully_qualified
- UINT32_MAX, searched_symbol_files, class_types);
-
- for (size_t i = 0; i < num_matches; ++i) {
- TypeSP type_sp = class_types.GetTypeAtIndex(i);
- CompilerType compiler_type = type_sp->GetFullCompilerType();
-
- if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava)
- continue;
-
- if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) {
- class_type_or_name.SetTypeSP(type_sp);
-
- Value &value = in_value.GetValue();
- value_type = value.GetValueType();
- dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0));
- return true;
- }
- }
- return false;
-}
-
-TypeAndOrName
-JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
- ValueObject &static_value) {
- CompilerType static_type(static_value.GetCompilerType());
-
- TypeAndOrName ret(type_and_or_name);
- if (type_and_or_name.HasType()) {
- CompilerType orig_type = type_and_or_name.GetCompilerType();
- if (static_type.IsReferenceType())
- ret.SetCompilerType(orig_type.GetLValueReferenceType());
- }
- return ret;
-}
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
deleted file mode 100644
index 6eeb4041572a..000000000000
--- a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- JavaLanguageRuntime.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_JavaLanguageRuntime_h_
-#define liblldb_JavaLanguageRuntime_h_
-
-// C Includes
-// C++ Includes
-#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/PluginInterface.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/lldb-private.h"
-
-namespace lldb_private {
-
-class JavaLanguageRuntime : public LanguageRuntime {
-public:
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::LanguageRuntime *
- CreateInstance(Process *process, lldb::LanguageType language);
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- lldb::LanguageType GetLanguageType() const override {
- return lldb::eLanguageTypeJava;
- }
-
- bool GetObjectDescription(Stream &str, ValueObject &object) override {
- return false;
- }
-
- bool GetObjectDescription(Stream &str, Value &value,
- ExecutionContextScope *exe_scope) override {
- return false;
- }
-
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt,
- bool catch_bp,
- bool throw_bp) override {
- return nullptr;
- }
-
- TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
- ValueObject &static_value) override;
-
- bool CouldHaveDynamicValue(ValueObject &in_value) override;
-
- bool GetDynamicTypeAndAddress(ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &address,
- Value::ValueType &value_type) override;
-
-protected:
- JavaLanguageRuntime(Process *process);
-
-private:
- DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_JavaLanguageRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index edb29e735ca9..679c3c850e5b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -264,11 +264,7 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) {
}
process->ReadCStringFromMemory(m_types_ptr, m_types, error);
- if (error.Fail()) {
- return false;
- }
-
- return true;
+ return !error.Fail();
}
bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) {
@@ -323,11 +319,7 @@ bool ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) {
}
process->ReadCStringFromMemory(m_type_ptr, m_type, error);
- if (error.Fail()) {
- return false;
- }
-
- return true;
+ return !error.Fail();
}
bool ClassDescriptorV2::Describe(
@@ -524,7 +516,8 @@ void ClassDescriptorV2::iVarsStorage::fill(AppleObjCRuntimeV2 &runtime,
LLDB_LOGV(log,
"name = {0}, encoding = {1}, offset_ptr = {2:x}, size = "
"{3}, type_size = {4}",
- name, type, offset_ptr, size, ivar_type.GetByteSize(nullptr));
+ name, type, offset_ptr, size,
+ ivar_type.GetByteSize(nullptr).getValueOr(0));
Scalar offset_scalar;
Status error;
const int offset_ptr_size = 4;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 787423b54766..308ff1426fb2 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -10,12 +10,8 @@
#ifndef liblldb_AppleObjCClassDescriptorV2_h_
#define liblldb_AppleObjCClassDescriptorV2_h_
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
-// Project includes
#include "AppleObjCRuntimeV2.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 105c088b9e91..4fc340b23c2c 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -558,7 +558,7 @@ AppleObjCDeclVendor::FindDecls(const ConstString &name, bool append,
LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log)
- log->Printf("AppleObjCDeclVendor::FindTypes [%u] ('%s', %s, %u, )",
+ log->Printf("AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )",
current_id, (const char *)name.AsCString(),
append ? "true" : "false", max_matches);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index 2f087da16bc1..7f5c0bf3eb63 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -10,10 +10,6 @@
#ifndef liblldb_AppleObjCDeclVendor_h_
#define liblldb_AppleObjCDeclVendor_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/DeclVendor.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index fef42c78b24f..ed47b481a810 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -17,13 +17,15 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -32,9 +34,13 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
+#include "Plugins/Language/ObjC/NSString.h"
+
#include <vector>
using namespace lldb;
@@ -167,6 +173,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value,
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeout(g_po_function_timeout);
+ options.SetIsForUtilityExpr(true);
ExpressionResults results = m_print_object_caller_up->ExecuteFunction(
exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
@@ -440,13 +447,10 @@ bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() {
SymbolContextList sc_list;
- if (target.GetImages().FindSymbolsWithNameAndType(s_method_signature,
- eSymbolTypeCode, sc_list) ||
- target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature,
- eSymbolTypeCode, sc_list))
- return true;
- else
- return false;
+ return target.GetImages().FindSymbolsWithNameAndType(
+ s_method_signature, eSymbolTypeCode, sc_list) ||
+ target.GetImages().FindSymbolsWithNameAndType(
+ s_arclite_method_signature, eSymbolTypeCode, sc_list);
}
lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
@@ -454,13 +458,115 @@ lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() {
if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) {
FileSpecList filter_modules;
- filter_modules.Append(FileSpec("libobjc.A.dylib", false));
+ filter_modules.Append(std::get<0>(GetExceptionThrowLocation()));
return target.GetSearchFilterForModuleList(&filter_modules);
} else {
return LanguageRuntime::CreateExceptionSearchFilter();
}
}
+ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread(
+ ThreadSP thread_sp) {
+ auto cpp_runtime = m_process->GetCPPLanguageRuntime();
+ if (!cpp_runtime) return ValueObjectSP();
+ auto cpp_exception = cpp_runtime->GetExceptionObjectForThread(thread_sp);
+ if (!cpp_exception) return ValueObjectSP();
+
+ auto descriptor = GetClassDescriptor(*cpp_exception.get());
+ if (!descriptor || !descriptor->IsValid()) return ValueObjectSP();
+
+ while (descriptor) {
+ ConstString class_name(descriptor->GetClassName());
+ if (class_name == ConstString("NSException")) return cpp_exception;
+ descriptor = descriptor->GetSuperclass();
+ }
+
+ return ValueObjectSP();
+}
+
+ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException(
+ lldb::ValueObjectSP exception_sp) {
+ ValueObjectSP reserved_dict =
+ exception_sp->GetChildMemberWithName(ConstString("reserved"), true);
+ if (!reserved_dict) return ThreadSP();
+
+ reserved_dict = reserved_dict->GetSyntheticValue();
+ if (!reserved_dict) return ThreadSP();
+
+ CompilerType objc_id =
+ exception_sp->GetTargetSP()->GetScratchClangASTContext()->GetBasicType(
+ lldb::eBasicTypeObjCID);
+ ValueObjectSP return_addresses;
+
+ auto objc_object_from_address = [&exception_sp, &objc_id](uint64_t addr,
+ const char *name) {
+ Value value(addr);
+ value.SetCompilerType(objc_id);
+ auto object = ValueObjectConstResult::Create(
+ exception_sp->GetTargetSP().get(), value, ConstString(name));
+ object = object->GetDynamicValue(eDynamicDontRunTarget);
+ return object;
+ };
+
+ for (size_t idx = 0; idx < reserved_dict->GetNumChildren(); idx++) {
+ ValueObjectSP dict_entry = reserved_dict->GetChildAtIndex(idx, true);
+
+ DataExtractor data;
+ data.SetAddressByteSize(dict_entry->GetProcessSP()->GetAddressByteSize());
+ Status error;
+ dict_entry->GetData(data, error);
+ if (error.Fail()) return ThreadSP();
+
+ lldb::offset_t data_offset = 0;
+ auto dict_entry_key = data.GetPointer(&data_offset);
+ auto dict_entry_value = data.GetPointer(&data_offset);
+
+ auto key_nsstring = objc_object_from_address(dict_entry_key, "key");
+ StreamString key_summary;
+ if (lldb_private::formatters::NSStringSummaryProvider(
+ *key_nsstring, key_summary, TypeSummaryOptions()) &&
+ !key_summary.Empty()) {
+ if (key_summary.GetString() == "\"callStackReturnAddresses\"") {
+ return_addresses = objc_object_from_address(dict_entry_value,
+ "callStackReturnAddresses");
+ break;
+ }
+ }
+ }
+
+ if (!return_addresses) return ThreadSP();
+ auto frames_value =
+ return_addresses->GetChildMemberWithName(ConstString("_frames"), true);
+ addr_t frames_addr = frames_value->GetValueAsUnsigned(0);
+ auto count_value =
+ return_addresses->GetChildMemberWithName(ConstString("_cnt"), true);
+ size_t count = count_value->GetValueAsUnsigned(0);
+ auto ignore_value =
+ return_addresses->GetChildMemberWithName(ConstString("_ignore"), true);
+ size_t ignore = ignore_value->GetValueAsUnsigned(0);
+
+ size_t ptr_size = m_process->GetAddressByteSize();
+ std::vector<lldb::addr_t> pcs;
+ for (size_t idx = 0; idx < count; idx++) {
+ Status error;
+ addr_t pc = m_process->ReadPointerFromMemory(
+ frames_addr + (ignore + idx) * ptr_size, error);
+ pcs.push_back(pc);
+ }
+
+ if (pcs.empty()) return ThreadSP();
+
+ ThreadSP new_thread_sp(new HistoryThread(*m_process, 0, pcs, 0, false));
+ m_process->GetExtendedThreadList().AddThread(new_thread_sp);
+ return new_thread_sp;
+}
+
+std::tuple<FileSpec, ConstString>
+AppleObjCRuntime::GetExceptionThrowLocation() {
+ return std::make_tuple(
+ FileSpec("libobjc.A.dylib"), ConstString("objc_exception_throw"));
+}
+
void AppleObjCRuntime::ReadObjCLibraryIfNeeded(const ModuleList &module_list) {
if (!HasReadObjCLibrary()) {
std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
index 1b22ee4c3be1..866064600149 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
@@ -10,12 +10,8 @@
#ifndef liblldb_AppleObjCRuntime_h_
#define liblldb_AppleObjCRuntime_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/Optional.h"
-// Project includes
#include "AppleObjCTrampolineHandler.h"
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
#include "lldb/Target/LanguageRuntime.h"
@@ -90,6 +86,14 @@ public:
bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override;
lldb::SearchFilterSP CreateExceptionSearchFilter() override;
+
+ static std::tuple<FileSpec, ConstString> GetExceptionThrowLocation();
+
+ lldb::ValueObjectSP GetExceptionObjectForThread(
+ lldb::ThreadSP thread_sp) override;
+
+ lldb::ThreadSP GetBacktraceThreadFromException(
+ lldb::ValueObjectSP thread_sp) override;
uint32_t GetFoundationVersion();
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 5001c0461b3b..1cfc7a1a022b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -17,7 +17,6 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -29,6 +28,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -58,7 +58,7 @@ bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress(
class_type_or_name.SetName(class_descriptor->GetClassName());
}
}
- return class_type_or_name.IsEmpty() == false;
+ return !class_type_or_name.IsEmpty();
}
//------------------------------------------------------------------
@@ -113,8 +113,9 @@ AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
if (throw_bp)
resolver_sp.reset(new BreakpointResolverName(
- bkpt, "objc_exception_throw", eFunctionNameTypeBase,
- eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo));
+ bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0,
+ eLazyBoolNo));
// FIXME: don't do catch yet.
return resolver_sp;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
index 52eec0f692fb..442a3a1fb5e1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
@@ -10,10 +10,6 @@
#ifndef liblldb_AppleObjCRuntimeV1_h_
#define liblldb_AppleObjCRuntimeV1_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "AppleObjCRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index d217ed3ff325..b6ed2fe376d3 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -7,18 +7,14 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stdint.h>
-// C++ Includes
#include <string>
#include <vector>
-// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
-// Project includes
#include "lldb/Core/ClangForward.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Symbol/CompilerType.h"
@@ -28,8 +24,8 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -44,14 +40,17 @@
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
@@ -377,6 +376,8 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name,
}
}
+static void RegisterObjCExceptionRecognizer();
+
AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
const ModuleSP &objc_module_sp)
: AppleObjCRuntime(process), m_get_class_info_code(),
@@ -397,6 +398,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(
g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ RegisterObjCExceptionRecognizer();
}
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
@@ -452,7 +454,7 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
}
}
}
- return class_type_or_name.IsEmpty() == false;
+ return !class_type_or_name.IsEmpty();
}
//------------------------------------------------------------------
@@ -475,9 +477,9 @@ LanguageRuntime *AppleObjCRuntimeV2::CreateInstance(Process *process,
return NULL;
}
-static OptionDefinition g_objc_classtable_dump_options[] = {
+static constexpr OptionDefinition g_objc_classtable_dump_options[] = {
{LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
+ nullptr, {}, 0, eArgTypeNone,
"Print ivar and method information in detail"}};
class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed {
@@ -803,8 +805,9 @@ AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp,
if (throw_bp)
resolver_sp.reset(new BreakpointResolverName(
- bkpt, "objc_exception_throw", eFunctionNameTypeBase,
- eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo));
+ bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(),
+ eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0,
+ eLazyBoolNo));
// FIXME: We don't do catch breakpoints for ObjC yet.
// Should there be some way for the runtime to specify what it can do in this
// regard?
@@ -1409,6 +1412,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeout(g_utility_function_timeout);
+ options.SetIsForUtilityExpr(true);
Value return_value;
return_value.SetValueType(Value::eValueTypeScalar);
@@ -1659,6 +1663,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() {
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeout(g_utility_function_timeout);
+ options.SetIsForUtilityExpr(true);
Value return_value;
return_value.SetValueType(Value::eValueTypeScalar);
@@ -1847,8 +1852,8 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() {
// warn if:
// - we could not run either expression
// - we found fewer than num_classes_to_warn_at classes total
- if ((false == shared_cache_update_result.m_update_ran) ||
- (false == dynamic_update_result.m_update_ran))
+ if ((!shared_cache_update_result.m_update_ran) ||
+ (!dynamic_update_result.m_update_ran))
WarnIfNoClassesCached(
SharedCacheWarningReason::eExpressionExecutionFailure);
else if (dynamic_update_result.m_num_found +
@@ -2423,7 +2428,7 @@ AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache(
ObjCLanguageRuntime::ClassDescriptorSP
AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) {
ObjCISA real_isa = 0;
- if (EvaluateNonPointerISA(isa, real_isa) == false)
+ if (!EvaluateNonPointerISA(isa, real_isa))
return ObjCLanguageRuntime::ClassDescriptorSP();
auto cache_iter = m_cache.find(real_isa);
if (cache_iter != m_cache.end())
@@ -2447,7 +2452,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
// 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
+ // Note, we check these variables 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 &&
@@ -2534,7 +2539,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA(
return false;
}
- // Definately not an indexed ISA, so try to use a mask to extract the pointer
+ // Definitely 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;
@@ -2594,3 +2599,62 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true,
} else
this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false);
}
+
+#pragma mark Frame recognizers
+
+class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame {
+ public:
+ ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) {
+ ThreadSP thread_sp = frame_sp->GetThread();
+ ProcessSP process_sp = thread_sp->GetProcess();
+
+ const lldb::ABISP &abi = process_sp->GetABI();
+ if (!abi) return;
+
+ CompilerType voidstar = process_sp->GetTarget()
+ .GetScratchClangASTContext()
+ ->GetBasicType(lldb::eBasicTypeVoid)
+ .GetPointerType();
+
+ ValueList args;
+ Value input_value;
+ input_value.SetCompilerType(voidstar);
+ args.PushValue(input_value);
+
+ if (!abi->GetArgumentValues(*thread_sp, args)) return;
+
+ addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong();
+
+ Value value(exception_addr);
+ value.SetCompilerType(voidstar);
+ exception = ValueObjectConstResult::Create(frame_sp.get(), value,
+ ConstString("exception"));
+ exception = exception->GetDynamicValue(eDynamicDontRunTarget);
+
+ m_arguments = ValueObjectListSP(new ValueObjectList());
+ m_arguments->Append(exception);
+ }
+
+ ValueObjectSP exception;
+
+ lldb::ValueObjectSP GetExceptionObject() override { return exception; }
+};
+
+class ObjCExceptionThrowFrameRecognizer : public StackFrameRecognizer {
+ lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) {
+ return lldb::RecognizedStackFrameSP(
+ new ObjCExceptionRecognizedStackFrame(frame));
+ };
+};
+
+static void RegisterObjCExceptionRecognizer() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
+ FileSpec module;
+ ConstString function;
+ std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation();
+ StackFrameRecognizerManager::AddRecognizer(
+ StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()),
+ module.GetFilename(), function, /*first_instruction_only*/ true);
+ });
+}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 487b67ca6271..aa91f857219b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -10,14 +10,10 @@
#ifndef liblldb_AppleObjCRuntimeV2_h_
#define liblldb_AppleObjCRuntimeV2_h_
-// C Includes
-// C++ Includes
#include <map>
#include <memory>
#include <mutex>
-// Other libraries and framework includes
-// Project includes
#include "AppleObjCRuntime.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index c75fa71ba131..e9182c590977 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -10,10 +10,6 @@
#include "AppleObjCTrampolineHandler.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
@@ -80,7 +76,7 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector ( \n\
void *super_ptr; \n\
}; \n\
struct __lldb_objc_super { \n\
- void *reciever; \n\
+ void *receiver; \n\
struct __lldb_objc_class *class_ptr; \n\
}; \n\
struct __lldb_msg_ref { \n\
@@ -202,7 +198,7 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object,
void *super_ptr; \n\
}; \n\
struct __lldb_objc_super { \n\
- void *reciever; \n\
+ void *receiver; \n\
struct __lldb_objc_class *class_ptr; \n\
}; \n\
struct __lldb_msg_ref { \n\
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index dc58a8bc1eb6..fe3390757d08 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -10,14 +10,10 @@
#ifndef lldb_AppleObjCTrampolineHandler_h_
#define lldb_AppleObjCTrampolineHandler_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/lldb-public.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
index 4da84dd92c3f..fac564e33165 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h
@@ -10,12 +10,8 @@
#ifndef liblldb_AppleObjCTypeEncodingParser_h_
#define liblldb_AppleObjCTypeEncodingParser_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/ASTContext.h"
-// Project includes
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 75b670739427..2b54d0a542d9 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -8,10 +8,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
#include "AppleObjCTrampolineHandler.h"
#include "lldb/Expression/DiagnosticManager.h"
@@ -161,13 +157,15 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(
eSymbolContextEverything);
+ Status status;
const bool abort_other_plans = false;
const bool first_insn = true;
const uint32_t frame_idx = 0;
m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop(
abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion,
- eVoteNoOpinion, frame_idx);
- m_run_to_sp->SetPrivate(true);
+ eVoteNoOpinion, frame_idx, status);
+ if (m_run_to_sp && status.Success())
+ m_run_to_sp->SetPrivate(true);
return false;
}
@@ -202,10 +200,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) {
// The base class MischiefManaged does some cleanup - so you have to call it in
// your MischiefManaged derived class.
bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() {
- if (IsPlanComplete())
- return true;
- else
- return false;
+ return IsPlanComplete();
}
bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; }
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
index 60c8b92d9cc7..5758e19f83ca 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
@@ -10,10 +10,6 @@
#ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_
#define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "AppleObjCTrampolineHandler.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/ThreadPlan.h"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
index cbbc35f1c08a..2c12cf9af637 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp
@@ -7,11 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Instruction.h"
@@ -24,7 +21,6 @@
#include "clang/Basic/TargetOptions.h"
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
index f45ff83c5a2b..647558171d1c 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h
@@ -10,15 +10,11 @@
#ifndef LLDB_RENDERSCRIPT_EXPROPTS_H
#define LLDB_RENDERSCRIPT_EXPROPTS_H
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-// Project includes
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 4eb15369aa1e..fa775d9bfa94 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/StringSwitch.h"
-// Project includes
#include "RenderScriptRuntime.h"
#include "RenderScriptScriptGroup.h"
@@ -20,7 +16,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Expression/UserExpression.h"
@@ -41,8 +36,8 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Status.h"
@@ -2079,10 +2074,8 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem,
// If this Element has subelements then JIT rsaElementGetSubElements() for
// details about its fields
- if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, frame_ptr))
- return false;
-
- return true;
+ return !(*elem.field_count.get() > 0 &&
+ !JITSubelements(elem, context, frame_ptr));
}
// JITs the RS runtime for information about the subelements/fields of a struct
@@ -2305,10 +2298,7 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc,
SetElementSize(alloc->element);
// Use GetOffsetPointer() to infer size of the allocation
- if (!JITAllocationSize(alloc, frame_ptr))
- return false;
-
- return true;
+ return JITAllocationSize(alloc, frame_ptr);
}
// Function attempts to set the type_name member of the paramaterised Element
@@ -2529,21 +2519,22 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
"Allocation information not available");
// Check we can read from file
- FileSpec file(path, true);
- if (!file.Exists()) {
+ FileSpec file(path);
+ FileSystem::Instance().Resolve(file);
+ if (!FileSystem::Instance().Exists(file)) {
strm.Printf("Error: File %s does not exist", path);
strm.EOL();
return false;
}
- if (!file.Readable()) {
+ if (!FileSystem::Instance().Readable(file)) {
strm.Printf("Error: File %s does not have readable permissions", path);
strm.EOL();
return false;
}
// Read file into data buffer
- auto data_sp = DataBufferLLVM::CreateFromPath(file.GetPath());
+ auto data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath());
// Cast start of buffer to FileHeader and use pointer to read metadata
void *file_buf = data_sp->GetBytes();
@@ -2753,9 +2744,14 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
"Allocation information not available");
// Check we can create writable file
- FileSpec file_spec(path, true);
- File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
- File::eOpenOptionTruncate);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ File file;
+ FileSystem::Instance().Open(file, file_spec,
+ File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate |
+ File::eOpenOptionTruncate);
+
if (!file) {
strm.Printf("Error: Failed to open '%s' for writing", path);
strm.EOL();
@@ -3079,7 +3075,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
const addr_t size = info_sym->GetByteSize();
const FileSpec fs = m_module->GetFileSpec();
- auto buffer = DataBufferLLVM::CreateSliceFromPath(fs.GetPath(), size, addr);
+ auto buffer =
+ FileSystem::Instance().CreateDataBuffer(fs.GetPath(), size, addr);
if (!buffer)
return false;
@@ -3718,7 +3715,8 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
continue;
// Find the function name
- const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+ const SymbolContext sym_ctx =
+ frame_sp->GetSymbolContext(eSymbolContextFunction);
const ConstString func_name = sym_ctx.GetFunctionName();
if (!func_name)
continue;
@@ -4171,13 +4169,13 @@ public:
}
};
-static OptionDefinition g_renderscript_reduction_bp_set_options[] = {
+static constexpr OptionDefinition g_renderscript_reduction_bp_set_options[] = {
{LLDB_OPT_SET_1, false, "function-role", 't',
- OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner,
+ OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner,
"Break on a comma separated set of reduction kernel types "
"(accumulator,outcoverter,combiner,initializer"},
{LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
- nullptr, nullptr, 0, eArgTypeValue,
+ nullptr, {}, 0, eArgTypeValue,
"Set a breakpoint on a single invocation of the kernel with specified "
"coordinate.\n"
"Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
@@ -4330,9 +4328,9 @@ private:
CommandOptions m_options;
};
-static OptionDefinition g_renderscript_kernel_bp_set_options[] = {
+static constexpr OptionDefinition g_renderscript_kernel_bp_set_options[] = {
{LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
- nullptr, nullptr, 0, eArgTypeValue,
+ nullptr, {}, 0, eArgTypeValue,
"Set a breakpoint on a single invocation of the kernel with specified "
"coordinate.\n"
"Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
@@ -4602,9 +4600,9 @@ public:
}
};
-static OptionDefinition g_renderscript_runtime_alloc_dump_options[] = {
+static constexpr OptionDefinition g_renderscript_runtime_alloc_dump_options[] = {
{LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument,
- nullptr, nullptr, 0, eArgTypeFilename,
+ nullptr, {}, 0, eArgTypeFilename,
"Print results to specified file instead of command line."}};
class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword {
@@ -4650,8 +4648,9 @@ public:
switch (short_option) {
case 'f':
- m_outfile.SetFile(option_arg, true, FileSpec::Style::native);
- if (m_outfile.Exists()) {
+ m_outfile.SetFile(option_arg, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(m_outfile);
+ if (FileSystem::Instance().Exists(m_outfile)) {
m_outfile.Clear();
err.SetErrorStringWithFormat("file already exists: '%s'",
option_arg.str().c_str());
@@ -4706,16 +4705,17 @@ public:
m_options.m_outfile; // Dump allocation to file instead
if (outfile_spec) {
// Open output file
- char path[256];
- outfile_spec.GetPath(path, sizeof(path));
- if (outfile_stream.GetFile()
- .Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate)
- .Success()) {
+ std::string path = outfile_spec.GetPath();
+ auto error = FileSystem::Instance().Open(
+ outfile_stream.GetFile(), outfile_spec,
+ File::eOpenOptionWrite | File::eOpenOptionCanCreate);
+ if (error.Success()) {
output_strm = &outfile_stream;
- result.GetOutputStream().Printf("Results written to '%s'", path);
+ result.GetOutputStream().Printf("Results written to '%s'",
+ path.c_str());
result.GetOutputStream().EOL();
} else {
- result.AppendErrorWithFormat("Couldn't open file '%s'", path);
+ result.AppendErrorWithFormat("Couldn't open file '%s'", path.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -4738,9 +4738,9 @@ private:
CommandOptions m_options;
};
-static OptionDefinition g_renderscript_runtime_alloc_list_options[] = {
+static constexpr OptionDefinition g_renderscript_runtime_alloc_list_options[] = {
{LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr,
- nullptr, 0, eArgTypeIndex,
+ {}, 0, eArgTypeIndex,
"Only show details of a single allocation with specified id."}};
class CommandObjectRenderScriptRuntimeAllocationList
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 0fe9134ce9e4..31714dd4a453 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -10,18 +10,14 @@
#ifndef liblldb_RenderScriptRuntime_h_
#define liblldb_RenderScriptRuntime_h_
-// C Includes
-// C++ Includes
#include <array>
#include <map>
#include <memory>
#include <string>
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Expression/LLVMUserExpression.h"
#include "lldb/Target/CPPLanguageRuntime.h"
@@ -74,7 +70,7 @@ public:
SymbolContext &context, Address *addr,
bool containing) override;
- Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
+ lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
CopyForBreakpoint(Breakpoint &breakpoint) override {
@@ -124,7 +120,7 @@ public:
SymbolContext &context, Address *addr,
bool containing) override;
- Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
+ lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
CopyForBreakpoint(Breakpoint &breakpoint) override {
@@ -269,7 +265,7 @@ public:
SymbolContext &context, Address *addr,
bool containing) override;
- Searcher::Depth GetDepth() override { return Searcher::eDepthModule; }
+ lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
lldb::BreakpointResolverSP
CopyForBreakpoint(Breakpoint &breakpoint) override {
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
index e1f8ea648414..0b298c90a50b 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp
@@ -7,11 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <set>
-// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
@@ -23,7 +20,6 @@
#include "llvm/IRReader/IRReader.h"
#include "llvm/Pass.h"
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
diff --git a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
index 31e9873fb1ee..c08acd0151ef 100644
--- a/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
+++ b/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h
@@ -10,10 +10,6 @@
#ifndef liblldb_MemoryHistoryASan_h_
#define liblldb_MemoryHistoryASan_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/ABI.h"
#include "lldb/Target/MemoryHistory.h"
#include "lldb/Target/Process.h"
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index 275f1fa2f70b..391ab7546967 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -33,7 +33,6 @@ typedef struct ar_hdr {
#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"
@@ -208,7 +207,7 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive(
while (pos != archive_map.end() && pos->first == file) {
bool match = true;
if (arch.IsValid() &&
- pos->second->GetArchitecture().IsCompatibleMatch(arch) == false)
+ !pos->second->GetArchitecture().IsCompatibleMatch(arch))
match = false;
else if (file_offset != LLDB_INVALID_OFFSET &&
pos->second->GetFileOffset() != file_offset)
@@ -313,7 +312,7 @@ ObjectContainer *ObjectContainerBSDArchive::CreateInstance(
// file gets updated by a new build while this .a file is being used for
// debugging
DataBufferSP archive_data_sp =
- DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+ FileSystem::Instance().CreateDataBuffer(*file, length, file_offset);
if (!archive_data_sp)
return nullptr;
@@ -461,14 +460,14 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications(
return 0;
const size_t initial_count = specs.GetSize();
- llvm::sys::TimePoint<> file_mod_time = FileSystem::GetModificationTime(file);
+ llvm::sys::TimePoint<> file_mod_time = FileSystem::Instance().GetModificationTime(file);
Archive::shared_ptr archive_sp(
Archive::FindCachedArchive(file, ArchSpec(), file_mod_time, file_offset));
bool set_archive_arch = false;
if (!archive_sp) {
set_archive_arch = true;
data_sp =
- DataBufferLLVM::CreateSliceFromPath(file.GetPath(), file_size, file_offset);
+ FileSystem::Instance().CreateDataBuffer(file, file_size, file_offset);
if (data_sp) {
data.SetData(data_sp, 0, data_sp->GetByteSize());
archive_sp = Archive::ParseAndCacheArchiveForFile(
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
index cb63eccff65e..86eaee1375a6 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -16,11 +16,8 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"
-// Other libraries and framework includes
#include "llvm/Support/Chrono.h"
-// C Includes
-// C++ Includes
#include <map>
#include <memory>
#include <mutex>
diff --git a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
index d3c0a080a6f9..d6e4fe1747cf 100644
--- a/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
+++ b/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
@@ -10,13 +10,9 @@
#ifndef liblldb_ObjectContainerUniversalMachO_h_
#define liblldb_ObjectContainerUniversalMachO_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/SafeMachO.h"
class ObjectContainerUniversalMachO : public lldb_private::ObjectContainer {
public:
diff --git a/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt b/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt
new file mode 100644
index 000000000000..2f51b2c8719a
--- /dev/null
+++ b/source/Plugins/ObjectFile/Breakpad/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginObjectFileBreakpad PLUGIN
+ ObjectFileBreakpad.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbUtility
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
new file mode 100644
index 000000000000..917025030ada
--- /dev/null
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
@@ -0,0 +1,315 @@
+//===-- ObjectFileBreakpad.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/ObjectFile/Breakpad/ObjectFileBreakpad.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::breakpad;
+
+namespace {
+struct Header {
+ ArchSpec arch;
+ UUID uuid;
+ static llvm::Optional<Header> parse(llvm::StringRef text);
+};
+
+enum class Token { Unknown, Module, Info, File, Func, Public, Stack };
+} // namespace
+
+static Token toToken(llvm::StringRef str) {
+ return llvm::StringSwitch<Token>(str)
+ .Case("MODULE", Token::Module)
+ .Case("INFO", Token::Info)
+ .Case("FILE", Token::File)
+ .Case("FUNC", Token::Func)
+ .Case("PUBLIC", Token::Public)
+ .Case("STACK", Token::Stack)
+ .Default(Token::Unknown);
+}
+
+static llvm::StringRef toString(Token t) {
+ switch (t) {
+ case Token::Unknown:
+ return "";
+ case Token::Module:
+ return "MODULE";
+ case Token::Info:
+ return "INFO";
+ case Token::File:
+ return "FILE";
+ case Token::Func:
+ return "FUNC";
+ case Token::Public:
+ return "PUBLIC";
+ case Token::Stack:
+ return "STACK";
+ }
+ llvm_unreachable("Unknown token!");
+}
+
+static llvm::Triple::OSType toOS(llvm::StringRef str) {
+ using llvm::Triple;
+ return llvm::StringSwitch<Triple::OSType>(str)
+ .Case("Linux", Triple::Linux)
+ .Case("mac", Triple::MacOSX)
+ .Case("windows", Triple::Win32)
+ .Default(Triple::UnknownOS);
+}
+
+static llvm::Triple::ArchType toArch(llvm::StringRef str) {
+ using llvm::Triple;
+ return llvm::StringSwitch<Triple::ArchType>(str)
+ .Case("arm", Triple::arm)
+ .Case("arm64", Triple::aarch64)
+ .Case("mips", Triple::mips)
+ .Case("ppc", Triple::ppc)
+ .Case("ppc64", Triple::ppc64)
+ .Case("s390", Triple::systemz)
+ .Case("sparc", Triple::sparc)
+ .Case("sparcv9", Triple::sparcv9)
+ .Case("x86", Triple::x86)
+ .Case("x86_64", Triple::x86_64)
+ .Default(Triple::UnknownArch);
+}
+
+static llvm::StringRef consume_front(llvm::StringRef &str, size_t n) {
+ llvm::StringRef result = str.take_front(n);
+ str = str.drop_front(n);
+ return result;
+}
+
+static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) {
+ struct uuid_data {
+ llvm::support::ulittle32_t uuid1;
+ llvm::support::ulittle16_t uuid2[2];
+ uint8_t uuid3[8];
+ llvm::support::ulittle32_t age;
+ } data;
+ static_assert(sizeof(data) == 20, "");
+ // The textual module id encoding should be between 33 and 40 bytes long,
+ // depending on the size of the age field, which is of variable length.
+ // The first three chunks of the id are encoded in big endian, so we need to
+ // byte-swap those.
+ if (str.size() < 33 || str.size() > 40)
+ return UUID();
+ uint32_t t;
+ if (to_integer(consume_front(str, 8), t, 16))
+ data.uuid1 = t;
+ else
+ return UUID();
+ for (int i = 0; i < 2; ++i) {
+ if (to_integer(consume_front(str, 4), t, 16))
+ data.uuid2[i] = t;
+ else
+ return UUID();
+ }
+ for (int i = 0; i < 8; ++i) {
+ if (!to_integer(consume_front(str, 2), data.uuid3[i], 16))
+ return UUID();
+ }
+ if (to_integer(str, t, 16))
+ data.age = t;
+ else
+ return UUID();
+
+ // On non-windows, the age field should always be zero, so we don't include to
+ // match the native uuid format of these platforms.
+ return UUID::fromData(&data, os == llvm::Triple::Win32 ? 20 : 16);
+}
+
+llvm::Optional<Header> Header::parse(llvm::StringRef text) {
+ // A valid module should start with something like:
+ // MODULE Linux x86_64 E5894855C35DCCCCCCCCCCCCCCCCCCCC0 a.out
+ // optionally followed by
+ // INFO CODE_ID 554889E55DC3CCCCCCCCCCCCCCCCCCCC [a.exe]
+ llvm::StringRef token, line;
+ std::tie(line, text) = text.split('\n');
+ std::tie(token, line) = getToken(line);
+ if (toToken(token) != Token::Module)
+ return llvm::None;
+
+ std::tie(token, line) = getToken(line);
+ llvm::Triple triple;
+ triple.setOS(toOS(token));
+ if (triple.getOS() == llvm::Triple::UnknownOS)
+ return llvm::None;
+
+ std::tie(token, line) = getToken(line);
+ triple.setArch(toArch(token));
+ if (triple.getArch() == llvm::Triple::UnknownArch)
+ return llvm::None;
+
+ llvm::StringRef module_id;
+ std::tie(module_id, line) = getToken(line);
+
+ std::tie(line, text) = text.split('\n');
+ std::tie(token, line) = getToken(line);
+ if (token == "INFO") {
+ std::tie(token, line) = getToken(line);
+ if (token != "CODE_ID")
+ return llvm::None;
+
+ std::tie(token, line) = getToken(line);
+ // If we don't have any text following the code id (e.g. on linux), we
+ // should use the module id as UUID. Otherwise, we revert back to the module
+ // id.
+ if (line.trim().empty()) {
+ UUID uuid;
+ if (uuid.SetFromStringRef(token, token.size() / 2) != token.size())
+ return llvm::None;
+
+ return Header{ArchSpec(triple), uuid};
+ }
+ }
+
+ // We reach here if we don't have a INFO CODE_ID section, or we chose not to
+ // use it. In either case, we need to properly decode the module id, whose
+ // fields are encoded in big-endian.
+ UUID uuid = parseModuleId(triple.getOS(), module_id);
+ if (!uuid)
+ return llvm::None;
+
+ return Header{ArchSpec(triple), uuid};
+}
+
+void ObjectFileBreakpad::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ CreateMemoryInstance, GetModuleSpecifications);
+}
+
+void ObjectFileBreakpad::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString ObjectFileBreakpad::GetPluginNameStatic() {
+ static ConstString g_name("breakpad");
+ return g_name;
+}
+
+ObjectFile *ObjectFileBreakpad::CreateInstance(
+ const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset,
+ const FileSpec *file, offset_t file_offset, offset_t length) {
+ if (!data_sp) {
+ data_sp = MapFileData(*file, length, file_offset);
+ if (!data_sp)
+ return nullptr;
+ data_offset = 0;
+ }
+ auto text = toStringRef(data_sp->GetData());
+ llvm::Optional<Header> header = Header::parse(text);
+ if (!header)
+ return nullptr;
+
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length) {
+ data_sp = MapFileData(*file, length, file_offset);
+ if (!data_sp)
+ return nullptr;
+ data_offset = 0;
+ }
+
+ return new ObjectFileBreakpad(module_sp, data_sp, data_offset, file,
+ file_offset, length, std::move(header->arch),
+ std::move(header->uuid));
+}
+
+ObjectFile *ObjectFileBreakpad::CreateMemoryInstance(
+ const ModuleSP &module_sp, DataBufferSP &data_sp,
+ const ProcessSP &process_sp, addr_t header_addr) {
+ return nullptr;
+}
+
+size_t ObjectFileBreakpad::GetModuleSpecifications(
+ const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset,
+ offset_t file_offset, offset_t length, ModuleSpecList &specs) {
+ auto text = toStringRef(data_sp->GetData());
+ llvm::Optional<Header> header = Header::parse(text);
+ if (!header)
+ return 0;
+ ModuleSpec spec(file, std::move(header->arch));
+ spec.GetUUID() = std::move(header->uuid);
+ specs.Append(spec);
+ return 1;
+}
+
+ObjectFileBreakpad::ObjectFileBreakpad(const ModuleSP &module_sp,
+ DataBufferSP &data_sp,
+ offset_t data_offset,
+ const FileSpec *file, offset_t offset,
+ offset_t length, ArchSpec arch,
+ UUID uuid)
+ : ObjectFile(module_sp, file, offset, length, data_sp, data_offset),
+ m_arch(std::move(arch)), m_uuid(std::move(uuid)) {}
+
+bool ObjectFileBreakpad::ParseHeader() {
+ // We already parsed the header during initialization.
+ return true;
+}
+
+Symtab *ObjectFileBreakpad::GetSymtab() {
+ // TODO
+ return nullptr;
+}
+
+bool ObjectFileBreakpad::GetUUID(UUID *uuid) {
+ *uuid = m_uuid;
+ return true;
+}
+
+void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
+ if (m_sections_ap)
+ return;
+ m_sections_ap = llvm::make_unique<SectionList>();
+
+ Token current_section = Token::Unknown;
+ offset_t section_start;
+ llvm::StringRef text = toStringRef(m_data.GetData());
+ uint32_t next_section_id = 1;
+ auto maybe_add_section = [&](const uint8_t *end_ptr) {
+ if (current_section == Token::Unknown)
+ return; // We have been called before parsing the first line.
+
+ offset_t end_offset = end_ptr - m_data.GetDataStart();
+ auto section_sp = std::make_shared<Section>(
+ GetModule(), this, next_section_id++,
+ ConstString(toString(current_section)), eSectionTypeOther,
+ /*file_vm_addr*/ 0, /*vm_size*/ 0, section_start,
+ end_offset - section_start, /*log2align*/ 0, /*flags*/ 0);
+ m_sections_ap->AddSection(section_sp);
+ unified_section_list.AddSection(section_sp);
+ };
+ while (!text.empty()) {
+ llvm::StringRef line;
+ std::tie(line, text) = text.split('\n');
+
+ Token token = toToken(getToken(line).first);
+ if (token == Token::Unknown) {
+ // We assume this is a line record, which logically belongs to the Func
+ // section. Errors will be handled when parsing the Func section.
+ token = Token::Func;
+ }
+ if (token == current_section)
+ continue;
+
+ // Changing sections, finish off the previous one, if there was any.
+ maybe_add_section(line.bytes_begin());
+ // And start a new one.
+ current_section = token;
+ section_start = line.bytes_begin() - m_data.GetDataStart();
+ }
+ // Finally, add the last section.
+ maybe_add_section(m_data.GetDataEnd());
+}
diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
new file mode 100644
index 000000000000..ba2a3ad30e5f
--- /dev/null
+++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
@@ -0,0 +1,109 @@
+//===-- ObjectFileBreakpad.h ---------------------------------- -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
+#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
+
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "llvm/ADT/Triple.h"
+
+namespace lldb_private {
+namespace breakpad {
+
+class ObjectFileBreakpad : public ObjectFile {
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+ static void Terminate();
+
+ static ConstString GetPluginNameStatic();
+ static const char *GetPluginDescriptionStatic() {
+ return "Breakpad object file reader.";
+ }
+
+ static ObjectFile *
+ CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset, const FileSpec *file,
+ lldb::offset_t file_offset, lldb::offset_t length);
+
+ static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp,
+ const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr);
+
+ static size_t GetModuleSpecifications(const FileSpec &file,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t data_offset,
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ ModuleSpecList &specs);
+
+ //------------------------------------------------------------------
+ // PluginInterface protocol
+ //------------------------------------------------------------------
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------------
+ // ObjectFile Protocol.
+ //------------------------------------------------------------------
+
+ bool ParseHeader() override;
+
+ lldb::ByteOrder GetByteOrder() const override {
+ return m_arch.GetByteOrder();
+ }
+
+ bool IsExecutable() const override { return false; }
+
+ uint32_t GetAddressByteSize() const override {
+ return m_arch.GetAddressByteSize();
+ }
+
+ AddressClass GetAddressClass(lldb::addr_t file_addr) override {
+ return AddressClass::eInvalid;
+ }
+
+ Symtab *GetSymtab() override;
+
+ bool IsStripped() override { return false; }
+
+ void CreateSections(SectionList &unified_section_list) override;
+
+ void Dump(Stream *s) override {}
+
+ ArchSpec GetArchitecture() override { return m_arch; }
+
+ bool GetUUID(UUID *uuid) override;
+
+ FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); }
+
+ uint32_t GetDependentModules(FileSpecList &files) override { return 0; }
+
+ Type CalculateType() override { return eTypeDebugInfo; }
+
+ Strata CalculateStrata() override { return eStrataUser; }
+
+private:
+ ArchSpec m_arch;
+ UUID m_uuid;
+
+ ObjectFileBreakpad(const lldb::ModuleSP &module_sp,
+ lldb::DataBufferSP &data_sp, lldb::offset_t data_offset,
+ const FileSpec *file, lldb::offset_t offset,
+ lldb::offset_t length, ArchSpec arch, UUID uuid);
+};
+
+} // namespace breakpad
+} // namespace lldb_private
+#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H
diff --git a/source/Plugins/ObjectFile/CMakeLists.txt b/source/Plugins/ObjectFile/CMakeLists.txt
index 06aa01c4f004..4edd667b9723 100644
--- a/source/Plugins/ObjectFile/CMakeLists.txt
+++ b/source/Plugins/ObjectFile/CMakeLists.txt
@@ -1,4 +1,5 @@
+add_subdirectory(Breakpad)
add_subdirectory(ELF)
add_subdirectory(Mach-O)
add_subdirectory(PECOFF)
-add_subdirectory(JIT) \ No newline at end of file
+add_subdirectory(JIT)
diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
index 16cbb6e5753b..3d4735286bf2 100644
--- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
+++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
@@ -38,7 +38,7 @@ static bool GetMaxU64(const lldb_private::DataExtractor &data,
lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value) {
- if (GetMaxU64(data, offset, value, byte_size) == false) {
+ if (!GetMaxU64(data, offset, value, byte_size)) {
*offset = saved_offset;
return false;
}
@@ -60,7 +60,7 @@ static bool GetMaxS64(const lldb_private::DataExtractor &data,
lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value) {
- if (GetMaxS64(data, offset, value, byte_size) == false) {
+ if (!GetMaxS64(data, offset, value, byte_size)) {
*offset = saved_offset;
return false;
}
@@ -133,7 +133,7 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data,
return false;
// Read e_entry, e_phoff and e_shoff.
- if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false)
+ if (!GetMaxU64(data, offset, &e_entry, byte_size, 3))
return false;
// Read e_flags.
@@ -232,11 +232,11 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
return false;
// Read sh_flags.
- if (GetMaxU64(data, offset, &sh_flags, byte_size) == false)
+ if (!GetMaxU64(data, offset, &sh_flags, byte_size))
return false;
// Read sh_addr, sh_off and sh_size.
- if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false)
+ if (!GetMaxU64(data, offset, &sh_addr, byte_size, 3))
return false;
// Read sh_link and sh_info.
@@ -244,7 +244,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
return false;
// Read sh_addralign and sh_entsize.
- if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false)
+ if (!GetMaxU64(data, offset, &sh_addralign, byte_size, 2))
return false;
return true;
@@ -332,7 +332,7 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data,
if (parsing_32) {
// Read st_value and st_size.
- if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false)
+ if (!GetMaxU64(data, offset, &st_value, byte_size, 2))
return false;
// Read st_info and st_other.
@@ -376,7 +376,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
if (parsing_32) {
// Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz.
- if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false)
+ if (!GetMaxU64(data, offset, &p_offset, byte_size, 5))
return false;
// Read p_flags.
@@ -384,7 +384,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
return false;
// Read p_align.
- if (GetMaxU64(data, offset, &p_align, byte_size) == false)
+ if (!GetMaxU64(data, offset, &p_align, byte_size))
return false;
} else {
// Read p_flags.
@@ -392,7 +392,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
return false;
// Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align.
- if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false)
+ if (!GetMaxU64(data, offset, &p_offset, byte_size, 6))
return false;
}
@@ -420,10 +420,7 @@ bool ELFRel::Parse(const lldb_private::DataExtractor &data,
const unsigned byte_size = data.GetAddressByteSize();
// Read r_offset and r_info.
- if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
- return false;
-
- return true;
+ return GetMaxU64(data, offset, &r_offset, byte_size, 2) != false;
}
//------------------------------------------------------------------------------
@@ -436,11 +433,11 @@ bool ELFRela::Parse(const lldb_private::DataExtractor &data,
const unsigned byte_size = data.GetAddressByteSize();
// Read r_offset and r_info.
- if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false)
+ if (!GetMaxU64(data, offset, &r_offset, byte_size, 2))
return false;
// Read r_addend;
- if (GetMaxS64(data, offset, &r_addend, byte_size) == false)
+ if (!GetMaxS64(data, offset, &r_addend, byte_size))
return false;
return true;
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 8701908378f1..9a6563afa0a0 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -17,7 +17,9 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/SectionLoadList.h"
@@ -29,6 +31,7 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Decompressor.h"
@@ -235,6 +238,8 @@ unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
} // end anonymous namespace
+static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; }
+
bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
// Read all fields.
if (data.GetU32(offset, &n_namesz, 3) == NULL)
@@ -433,9 +438,8 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
if (address_size == 4 || address_size == 8) {
std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(
module_sp, data_sp, data_offset, file, file_offset, length));
- ArchSpec spec;
- if (objfile_ap->GetArchitecture(spec) &&
- objfile_ap->SetModulesArchitecture(spec))
+ ArchSpec spec = objfile_ap->GetArchitecture();
+ if (spec && objfile_ap->SetModulesArchitecture(spec))
return objfile_ap.release();
}
@@ -452,9 +456,8 @@ ObjectFile *ObjectFileELF::CreateMemoryInstance(
if (address_size == 4 || address_size == 8) {
std::unique_ptr<ObjectFileELF> objfile_ap(
new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
- ArchSpec spec;
- if (objfile_ap->GetArchitecture(spec) &&
- objfile_ap->SetModulesArchitecture(spec))
+ ArchSpec spec = objfile_ap->GetArchitecture();
+ if (spec && objfile_ap->SetModulesArchitecture(spec))
return objfile_ap.release();
}
}
@@ -538,14 +541,13 @@ static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
const ProgramHeaderColl &program_headers, DataExtractor &object_data) {
- typedef ProgramHeaderCollConstIter Iter;
uint32_t core_notes_crc = 0;
- for (Iter I = program_headers.begin(); I != program_headers.end(); ++I) {
- if (I->p_type == llvm::ELF::PT_NOTE) {
- const elf_off ph_offset = I->p_offset;
- const size_t ph_size = I->p_filesz;
+ for (const ELFProgramHeader &H : program_headers) {
+ if (H.p_type == llvm::ELF::PT_NOTE) {
+ const elf_off ph_offset = H.p_offset;
+ const size_t ph_size = H.p_filesz;
DataExtractor segment_data;
if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
@@ -713,7 +715,8 @@ size_t ObjectFileELF::GetModuleSpecifications(
func_cat,
"Calculating module crc32 %s with size %" PRIu64 " KiB",
file.GetLastPathComponent().AsCString(),
- (file.GetByteSize() - file_offset) / 1024);
+ (FileSystem::Instance().GetByteSize(file) - file_offset) /
+ 1024);
// For core files - which usually don't happen to have a
// gnu_debuglink, and are pretty bulky - calculating whole
@@ -803,21 +806,10 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
SectionList *section_list = GetSectionList();
if (section_list) {
if (!value_is_offset) {
- bool found_offset = false;
- for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) {
- const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
- if (header == nullptr)
- continue;
-
- if (header->p_type != PT_LOAD || header->p_offset != 0)
- continue;
-
- value = value - header->p_vaddr;
- found_offset = true;
- break;
- }
- if (!found_offset)
+ addr_t base = GetBaseAddress().GetFileAddress();
+ if (base == LLDB_INVALID_ADDRESS)
return false;
+ value -= base;
}
const size_t num_sections = section_list->GetSize();
@@ -827,7 +819,8 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
// Iterate through the object file sections to find all of the sections
// that have SHF_ALLOC in their flag bits.
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
- if (section_sp && section_sp->Test(SHF_ALLOC)) {
+ if (section_sp->Test(SHF_ALLOC) ||
+ section_sp->GetType() == eSectionTypeContainer) {
lldb::addr_t load_addr = section_sp->GetFileAddress();
// We don't want to update the load address of a section with type
// eSectionTypeAbsoluteAddress as they already have the absolute load
@@ -892,11 +885,11 @@ AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
}
size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
- return std::distance(m_section_headers.begin(), I) + 1u;
+ return std::distance(m_section_headers.begin(), I);
}
size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
- return std::distance(m_section_headers.begin(), I) + 1u;
+ return std::distance(m_section_headers.begin(), I);
}
bool ObjectFileELF::ParseHeader() {
@@ -953,7 +946,7 @@ lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
FileSpecList file_spec_list;
if (!m_gnu_debuglink_file.empty()) {
- FileSpec file_spec(m_gnu_debuglink_file, false);
+ FileSpec file_spec(m_gnu_debuglink_file);
file_spec_list.Append(file_spec);
}
return file_spec_list;
@@ -1055,6 +1048,18 @@ lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
return m_entry_point_address;
}
+Address ObjectFileELF::GetBaseAddress() {
+ for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
+ const ELFProgramHeader &H = EnumPHdr.value();
+ if (H.p_type != PT_LOAD)
+ continue;
+
+ return Address(
+ GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0);
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
//----------------------------------------------------------------------
// ParseDependentModules
//----------------------------------------------------------------------
@@ -1084,7 +1089,7 @@ size_t ObjectFileELF::ParseDependentModules() {
return 0;
// sh_link: section header index of string table used by entries in the
// section.
- Section *dynstr = section_list->FindSectionByID(header->sh_link + 1).get();
+ Section *dynstr = section_list->FindSectionByID(header->sh_link).get();
if (!dynstr)
return 0;
@@ -1107,7 +1112,9 @@ size_t ObjectFileELF::ParseDependentModules() {
uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
const char *lib_name = dynstr_data.PeekCStr(str_index);
- m_filespec_ap->Append(FileSpec(lib_name, true));
+ FileSpec file_spec(lib_name);
+ FileSystem::Instance().Resolve(file_spec);
+ m_filespec_ap->Append(file_spec);
}
}
@@ -1141,7 +1148,7 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
uint32_t idx;
lldb::offset_t offset;
for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) {
- if (program_headers[idx].Parse(data, &offset) == false)
+ if (!program_headers[idx].Parse(data, &offset))
break;
}
@@ -1154,8 +1161,8 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
//----------------------------------------------------------------------
// ParseProgramHeaders
//----------------------------------------------------------------------
-size_t ObjectFileELF::ParseProgramHeaders() {
- return GetProgramHeaderInfo(m_program_headers, m_data, m_header);
+bool ObjectFileELF::ParseProgramHeaders() {
+ return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;
}
lldb_private::Status
@@ -1390,7 +1397,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
// In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some
// cases (e.g. compile with -nostdlib) Hence set OS to Linux
- arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
+ arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
}
}
@@ -1494,7 +1501,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
const uint32_t sub_type = subTypeFromElfHeader(header);
arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
header.e_ident[EI_OSABI]);
-
+
// Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is
// determined based on EI_OSABI flag and the info extracted from ELF notes
// (see RefineModuleDetailsFromNote). However in some cases that still
@@ -1553,7 +1560,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
uint32_t idx;
lldb::offset_t offset;
for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) {
- if (section_headers[idx].Parse(sh_data, &offset) == false)
+ if (!section_headers[idx].Parse(sh_data, &offset))
break;
}
if (idx < section_headers.size())
@@ -1701,27 +1708,6 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
return 0;
}
-size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); }
-
-const elf::ELFProgramHeader *
-ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) {
- if (!id || !ParseProgramHeaders())
- return NULL;
-
- if (--id < m_program_headers.size())
- return &m_program_headers[id];
-
- return NULL;
-}
-
-DataExtractor ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) {
- const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id);
- if (segment_header == NULL)
- return DataExtractor();
- return DataExtractor(m_data, segment_header->p_offset,
- segment_header->p_filesz);
-}
-
llvm::StringRef
ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
size_t pos = symbol_name.find('@');
@@ -1739,10 +1725,10 @@ size_t ObjectFileELF::ParseSectionHeaders() {
const ObjectFileELF::ELFSectionHeaderInfo *
ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
- if (!id || !ParseSectionHeaders())
+ if (!ParseSectionHeaders())
return NULL;
- if (--id < m_section_headers.size())
+ if (id < m_section_headers.size())
return &m_section_headers[id];
return NULL;
@@ -1757,233 +1743,273 @@ lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
return 0;
}
-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;
-
- ConstString &name = I->section_name;
- const uint64_t file_size =
- header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
- const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0;
-
- static ConstString g_sect_name_text(".text");
- static ConstString g_sect_name_data(".data");
- static ConstString g_sect_name_bss(".bss");
- static ConstString g_sect_name_tdata(".tdata");
- static ConstString g_sect_name_tbss(".tbss");
- 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");
- static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
- static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_macro(".debug_macro");
- static ConstString g_sect_name_dwarf_debug_names(".debug_names");
- static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str(".debug_str");
- static ConstString g_sect_name_dwarf_debug_str_offsets(
- ".debug_str_offsets");
- static ConstString g_sect_name_dwarf_debug_abbrev_dwo(
- ".debug_abbrev.dwo");
- static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo");
- static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo");
- static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo");
- static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo");
- static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
- static ConstString g_sect_name_dwarf_debug_str_offsets_dwo(
- ".debug_str_offsets.dwo");
- static ConstString g_sect_name_dwarf_debug_types(".debug_types");
- static ConstString g_sect_name_eh_frame(".eh_frame");
- static ConstString g_sect_name_arm_exidx(".ARM.exidx");
- static ConstString g_sect_name_arm_extab(".ARM.extab");
- static ConstString g_sect_name_go_symtab(".gosymtab");
- static ConstString g_sect_name_dwarf_gnu_debugaltlink(".gnu_debugaltlink");
-
- SectionType sect_type = eSectionTypeOther;
-
- bool is_thread_specific = false;
-
- if (name == g_sect_name_text)
- sect_type = eSectionTypeCode;
- else if (name == g_sect_name_data)
- sect_type = eSectionTypeData;
- else if (name == g_sect_name_bss)
- sect_type = eSectionTypeZeroFill;
- else if (name == g_sect_name_tdata) {
- sect_type = eSectionTypeData;
- is_thread_specific = true;
- } else if (name == g_sect_name_tbss) {
- sect_type = eSectionTypeZeroFill;
- is_thread_specific = true;
- }
- // .debug_abbrev – Abbreviations used in the .debug_info section
- // .debug_aranges – Lookup table for mapping addresses to compilation
- // units .debug_frame – Call frame information .debug_info – The core
- // DWARF information section .debug_line – Line number information
- // .debug_loc – Location lists used in DW_AT_location attributes
- // .debug_macinfo – Macro information .debug_pubnames – Lookup table
- // for mapping object and function names to compilation units
- // .debug_pubtypes – Lookup table for mapping type names to compilation
- // units .debug_ranges – Address ranges used in DW_AT_ranges attributes
- // .debug_str – String table used in .debug_info MISSING?
- // .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section,
- // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html MISSING?
- // .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build
- // /gdb-add-index?pathrev=144644 MISSING? .debug_types - Type
- // descriptions from DWARF 4? See
- // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
- else if (name == g_sect_name_dwarf_debug_abbrev)
- sect_type = eSectionTypeDWARFDebugAbbrev;
- else if (name == g_sect_name_dwarf_debug_addr)
- 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)
- sect_type = eSectionTypeDWARFDebugInfo;
- else if (name == g_sect_name_dwarf_debug_line)
- sect_type = eSectionTypeDWARFDebugLine;
- else if (name == g_sect_name_dwarf_debug_loc)
- sect_type = eSectionTypeDWARFDebugLoc;
- else if (name == g_sect_name_dwarf_debug_macinfo)
- sect_type = eSectionTypeDWARFDebugMacInfo;
- else if (name == g_sect_name_dwarf_debug_macro)
- sect_type = eSectionTypeDWARFDebugMacro;
- else if (name == g_sect_name_dwarf_debug_names)
- sect_type = eSectionTypeDWARFDebugNames;
- else if (name == g_sect_name_dwarf_debug_pubnames)
- sect_type = eSectionTypeDWARFDebugPubNames;
- else if (name == g_sect_name_dwarf_debug_pubtypes)
- sect_type = eSectionTypeDWARFDebugPubTypes;
- else if (name == g_sect_name_dwarf_debug_ranges)
- sect_type = eSectionTypeDWARFDebugRanges;
- else if (name == g_sect_name_dwarf_debug_str)
- sect_type = eSectionTypeDWARFDebugStr;
- else if (name == g_sect_name_dwarf_debug_types)
- sect_type = eSectionTypeDWARFDebugTypes;
- else if (name == g_sect_name_dwarf_debug_str_offsets)
- sect_type = eSectionTypeDWARFDebugStrOffsets;
- else if (name == g_sect_name_dwarf_debug_abbrev_dwo)
- sect_type = eSectionTypeDWARFDebugAbbrev;
- else if (name == g_sect_name_dwarf_debug_info_dwo)
- sect_type = eSectionTypeDWARFDebugInfo;
- else if (name == g_sect_name_dwarf_debug_line_dwo)
- sect_type = eSectionTypeDWARFDebugLine;
- else if (name == g_sect_name_dwarf_debug_macro_dwo)
- sect_type = eSectionTypeDWARFDebugMacro;
- else if (name == g_sect_name_dwarf_debug_loc_dwo)
- sect_type = eSectionTypeDWARFDebugLoc;
- else if (name == g_sect_name_dwarf_debug_str_dwo)
- sect_type = eSectionTypeDWARFDebugStr;
- else if (name == g_sect_name_dwarf_debug_str_offsets_dwo)
- sect_type = eSectionTypeDWARFDebugStrOffsets;
- else if (name == g_sect_name_eh_frame)
- sect_type = eSectionTypeEHFrame;
- else if (name == g_sect_name_arm_exidx)
- sect_type = eSectionTypeARMexidx;
- else if (name == g_sect_name_arm_extab)
- sect_type = eSectionTypeARMextab;
- else if (name == g_sect_name_go_symtab)
- sect_type = eSectionTypeGoSymtab;
- else if (name == g_sect_name_dwarf_gnu_debugaltlink)
- sect_type = eSectionTypeDWARFGNUDebugAltLink;
-
- const uint32_t permissions =
- ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) |
- ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0u) |
- ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0u);
- switch (header.sh_type) {
- case SHT_SYMTAB:
- assert(sect_type == eSectionTypeOther);
- sect_type = eSectionTypeELFSymbolTable;
- break;
- case SHT_DYNSYM:
- assert(sect_type == eSectionTypeOther);
- sect_type = eSectionTypeELFDynamicSymbols;
- break;
- case SHT_RELA:
- case SHT_REL:
- assert(sect_type == eSectionTypeOther);
- sect_type = eSectionTypeELFRelocationEntries;
- break;
- case SHT_DYNAMIC:
- assert(sect_type == eSectionTypeOther);
- sect_type = eSectionTypeELFDynamicLinkInfo;
- break;
- }
+static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
+ return llvm::StringSwitch<SectionType>(Name)
+ .Case(".ARM.exidx", eSectionTypeARMexidx)
+ .Case(".ARM.extab", eSectionTypeARMextab)
+ .Cases(".bss", ".tbss", eSectionTypeZeroFill)
+ .Cases(".data", ".tdata", eSectionTypeData)
+ .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev)
+ .Case(".debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
+ .Case(".debug_addr", eSectionTypeDWARFDebugAddr)
+ .Case(".debug_aranges", eSectionTypeDWARFDebugAranges)
+ .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex)
+ .Case(".debug_frame", eSectionTypeDWARFDebugFrame)
+ .Case(".debug_info", eSectionTypeDWARFDebugInfo)
+ .Case(".debug_info.dwo", eSectionTypeDWARFDebugInfoDwo)
+ .Cases(".debug_line", ".debug_line.dwo", eSectionTypeDWARFDebugLine)
+ .Cases(".debug_line_str", ".debug_line_str.dwo",
+ eSectionTypeDWARFDebugLineStr)
+ .Cases(".debug_loc", ".debug_loc.dwo", eSectionTypeDWARFDebugLoc)
+ .Cases(".debug_loclists", ".debug_loclists.dwo",
+ eSectionTypeDWARFDebugLocLists)
+ .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo)
+ .Cases(".debug_macro", ".debug_macro.dwo", eSectionTypeDWARFDebugMacro)
+ .Case(".debug_names", eSectionTypeDWARFDebugNames)
+ .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames)
+ .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
+ .Case(".debug_ranges", eSectionTypeDWARFDebugRanges)
+ .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists)
+ .Case(".debug_str", eSectionTypeDWARFDebugStr)
+ .Case(".debug_str.dwo", eSectionTypeDWARFDebugStrDwo)
+ .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
+ .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
+ .Case(".debug_types", eSectionTypeDWARFDebugTypes)
+ .Case(".eh_frame", eSectionTypeEHFrame)
+ .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
+ .Case(".gosymtab", eSectionTypeGoSymtab)
+ .Case(".text", eSectionTypeCode)
+ .Default(eSectionTypeOther);
+}
+
+SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const {
+ switch (H.sh_type) {
+ case SHT_PROGBITS:
+ if (H.sh_flags & SHF_EXECINSTR)
+ return eSectionTypeCode;
+ break;
+ case SHT_SYMTAB:
+ return eSectionTypeELFSymbolTable;
+ case SHT_DYNSYM:
+ return eSectionTypeELFDynamicSymbols;
+ case SHT_RELA:
+ case SHT_REL:
+ return eSectionTypeELFRelocationEntries;
+ case SHT_DYNAMIC:
+ return eSectionTypeELFDynamicLinkInfo;
+ }
+ SectionType Type = GetSectionTypeFromName(H.section_name.GetStringRef());
+ if (Type == eSectionTypeOther) {
+ // the kalimba toolchain assumes that ELF section names are free-form.
+ // It does support linkscripts which (can) give rise to various
+ // arbitrarily named sections being "Code" or "Data".
+ Type = kalimbaSectionType(m_header, H);
+ }
+ return Type;
+}
+
+static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) {
+ switch (Type) {
+ case eSectionTypeData:
+ case eSectionTypeZeroFill:
+ return arch.GetDataByteSize();
+ case eSectionTypeCode:
+ return arch.GetCodeByteSize();
+ default:
+ return 1;
+ }
+}
- if (eSectionTypeOther == sect_type) {
- // the kalimba toolchain assumes that ELF section names are free-form.
- // It does support linkscripts which (can) give rise to various
- // arbitrarily named sections being "Code" or "Data".
- sect_type = kalimbaSectionType(m_header, header);
- }
+static Permissions GetPermissions(const ELFSectionHeader &H) {
+ Permissions Perm = Permissions(0);
+ if (H.sh_flags & SHF_ALLOC)
+ Perm |= ePermissionsReadable;
+ if (H.sh_flags & SHF_WRITE)
+ Perm |= ePermissionsWritable;
+ if (H.sh_flags & SHF_EXECINSTR)
+ Perm |= ePermissionsExecutable;
+ return Perm;
+}
- // In common case ELF code section can have arbitrary name (for example,
- // we can specify it using section attribute for particular function) so
- // assume that section is a code section if it has SHF_EXECINSTR flag set
- // and has SHT_PROGBITS type.
- if (eSectionTypeOther == sect_type &&
- llvm::ELF::SHT_PROGBITS == header.sh_type &&
- (header.sh_flags & SHF_EXECINSTR)) {
- sect_type = eSectionTypeCode;
- }
+static Permissions GetPermissions(const ELFProgramHeader &H) {
+ Permissions Perm = Permissions(0);
+ if (H.p_flags & PF_R)
+ Perm |= ePermissionsReadable;
+ if (H.p_flags & PF_W)
+ Perm |= ePermissionsWritable;
+ if (H.p_flags & PF_X)
+ Perm |= ePermissionsExecutable;
+ return Perm;
+}
- const uint32_t target_bytes_size =
- (eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type)
- ? 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;
- }
+namespace {
+
+using VMRange = lldb_private::Range<addr_t, addr_t>;
- SectionSP section_sp(new Section(
- GetModule(), // Module to which this section belongs.
- this, // ObjectFile to which this section belongs and should read
- // section data from.
- SectionIndex(I), // Section ID.
- name, // Section name.
- sect_type, // Section type.
- 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.
- log2align, // Alignment of the section
- header.sh_flags, // Flags for this section.
- target_bytes_size)); // Number of host bytes per target byte
-
- section_sp->SetPermissions(permissions);
- if (is_thread_specific)
- section_sp->SetIsThreadSpecific(is_thread_specific);
- m_sections_ap->AddSection(section_sp);
+struct SectionAddressInfo {
+ SectionSP Segment;
+ VMRange Range;
+};
+
+// (Unlinked) ELF object files usually have 0 for every section address, meaning
+// we need to compute synthetic addresses in order for "file addresses" from
+// different sections to not overlap. This class handles that logic.
+class VMAddressProvider {
+ using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
+ llvm::IntervalMapHalfOpenInfo<addr_t>>;
+
+ ObjectFile::Type ObjectType;
+ addr_t NextVMAddress = 0;
+ VMMap::Allocator Alloc;
+ VMMap Segments = VMMap(Alloc);
+ VMMap Sections = VMMap(Alloc);
+ lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+
+ VMRange GetVMRange(const ELFSectionHeader &H) {
+ addr_t Address = H.sh_addr;
+ addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
+ if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
+ NextVMAddress =
+ llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
+ Address = NextVMAddress;
+ NextVMAddress += Size;
}
+ return VMRange(Address, Size);
+ }
+
+public:
+ VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {}
+
+ llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
+ if (H.p_memsz == 0) {
+ LLDB_LOG(Log,
+ "Ignoring zero-sized PT_LOAD segment. Corrupt object file?");
+ return llvm::None;
+ }
+
+ if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
+ LLDB_LOG(Log,
+ "Ignoring overlapping PT_LOAD segment. Corrupt object file?");
+ return llvm::None;
+ }
+ return VMRange(H.p_vaddr, H.p_memsz);
+ }
+
+ llvm::Optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) {
+ VMRange Range = GetVMRange(H);
+ SectionSP Segment;
+ auto It = Segments.find(Range.GetRangeBase());
+ if ((H.sh_flags & SHF_ALLOC) && It.valid()) {
+ addr_t MaxSize;
+ if (It.start() <= Range.GetRangeBase()) {
+ MaxSize = It.stop() - Range.GetRangeBase();
+ Segment = *It;
+ } else
+ MaxSize = It.start() - Range.GetRangeBase();
+ if (Range.GetByteSize() > MaxSize) {
+ LLDB_LOG(Log, "Shortening section crossing segment boundaries. "
+ "Corrupt object file?");
+ Range.SetByteSize(MaxSize);
+ }
+ }
+ if (Range.GetByteSize() > 0 &&
+ Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) {
+ LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?");
+ return llvm::None;
+ }
+ if (Segment)
+ Range.Slide(-Segment->GetFileAddress());
+ return SectionAddressInfo{Segment, Range};
+ }
+
+ void AddSegment(const VMRange &Range, SectionSP Seg) {
+ Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
+ }
+
+ void AddSection(SectionAddressInfo Info, SectionSP Sect) {
+ if (Info.Range.GetByteSize() == 0)
+ return;
+ if (Info.Segment)
+ Info.Range.Slide(Info.Segment->GetFileAddress());
+ Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
+ std::move(Sect));
+ }
+};
+}
+
+void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
+ if (m_sections_ap)
+ return;
+
+ m_sections_ap = llvm::make_unique<SectionList>();
+ VMAddressProvider address_provider(CalculateType());
+
+ size_t LoadID = 0;
+ for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
+ const ELFProgramHeader &PHdr = EnumPHdr.value();
+ if (PHdr.p_type != PT_LOAD)
+ continue;
+
+ auto InfoOr = address_provider.GetAddressInfo(PHdr);
+ if (!InfoOr)
+ continue;
+
+ ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str());
+ uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
+ SectionSP Segment = std::make_shared<Section>(
+ GetModule(), this, SegmentID(EnumPHdr.index()), Name,
+ eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),
+ PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);
+ Segment->SetPermissions(GetPermissions(PHdr));
+ m_sections_ap->AddSection(Segment);
+
+ address_provider.AddSegment(*InfoOr, std::move(Segment));
+ }
+
+ ParseSectionHeaders();
+ if (m_section_headers.empty())
+ return;
+
+ for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
+ I != m_section_headers.end(); ++I) {
+ const ELFSectionHeaderInfo &header = *I;
+
+ ConstString &name = I->section_name;
+ const uint64_t file_size =
+ header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
+
+ auto InfoOr = address_provider.GetAddressInfo(header);
+ if (!InfoOr)
+ continue;
+
+ SectionType sect_type = GetSectionType(header);
+
+ const uint32_t target_bytes_size =
+ GetTargetByteSize(sect_type, m_arch_spec);
+
+ elf::elf_xword log2align =
+ (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
+
+ SectionSP section_sp(new Section(
+ InfoOr->Segment, GetModule(), // Module to which this section belongs.
+ this, // ObjectFile to which this section belongs and should
+ // read section data from.
+ SectionIndex(I), // Section ID.
+ name, // Section name.
+ sect_type, // Section type.
+ InfoOr->Range.GetRangeBase(), // VM address.
+ InfoOr->Range.GetByteSize(), // 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.
+ log2align, // Alignment of the section
+ header.sh_flags, // Flags for this section.
+ target_bytes_size)); // Number of host bytes per target byte
+
+ section_sp->SetPermissions(GetPermissions(header));
+ section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
+ (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_ap)
+ .AddSection(section_sp);
+ address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
// For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
@@ -2050,8 +2076,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
bool skip_oatdata_oatexec = file_extension == ConstString(".oat") ||
file_extension == ConstString(".odex");
- ArchSpec arch;
- GetArchitecture(arch);
+ ArchSpec arch = GetArchitecture();
ModuleSP module_sp(GetModule());
SectionList *module_section_list =
module_sp ? module_sp->GetSectionList() : nullptr;
@@ -2063,7 +2088,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
unsigned i;
for (i = 0; i < num_symbols; ++i) {
- if (symbol.Parse(symtab_data, &offset) == false)
+ if (!symbol.Parse(symtab_data, &offset))
break;
const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
@@ -2083,9 +2108,9 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
SectionSP symbol_section_sp;
SymbolType symbol_type = eSymbolTypeInvalid;
- Elf64_Half section_idx = symbol.st_shndx;
+ Elf64_Half shndx = symbol.st_shndx;
- switch (section_idx) {
+ switch (shndx) {
case SHN_ABS:
symbol_type = eSymbolTypeAbsolute;
break;
@@ -2093,7 +2118,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
symbol_type = eSymbolTypeUndefined;
break;
default:
- symbol_section_sp = section_list->GetSectionAtIndex(section_idx);
+ symbol_section_sp = section_list->FindSectionByID(shndx);
break;
}
@@ -2262,7 +2287,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
// symbols. See above for more details.
uint64_t symbol_value = symbol.st_value + symbol_value_offset;
- if (symbol_section_sp == nullptr && section_idx == SHN_ABS &&
+ if (symbol_section_sp == nullptr && shndx == SHN_ABS &&
symbol.st_size != 0) {
// We don't have a section for a symbol with non-zero size. Create a new
// section for it so the address range covered by the symbol is also
@@ -2375,9 +2400,8 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
assert(symtab_hdr->sh_type == SHT_SYMTAB ||
symtab_hdr->sh_type == SHT_DYNSYM);
- // sh_link: section header index of associated string table. Section ID's are
- // ones based.
- user_id_t strtab_id = symtab_hdr->sh_link + 1;
+ // sh_link: section header index of associated string table.
+ user_id_t strtab_id = symtab_hdr->sh_link;
Section *strtab = section_list->FindSectionByID(strtab_id).get();
if (symtab && strtab) {
@@ -2529,7 +2553,7 @@ static unsigned ParsePLTRelocations(
unsigned slot_type = hdr->GetRelocationJumpSlotType();
unsigned i;
for (i = 0; i < num_relocations; ++i) {
- if (rel.Parse(rel_data, &offset) == false)
+ if (!rel.Parse(rel_data, &offset))
break;
if (reloc_type(rel) != slot_type)
@@ -2587,10 +2611,6 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
if (!symtab_id || !plt_id)
return 0;
- // Section ID's are ones based;
- symtab_id++;
- plt_id++;
-
const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
if (!plt_hdr)
return 0;
@@ -2616,7 +2636,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
return 0;
// sh_link points to associated string table.
- Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get();
+ Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get();
if (!strtab)
return 0;
@@ -2662,7 +2682,7 @@ unsigned ObjectFileELF::ApplyRelocations(
}
for (unsigned i = 0; i < num_relocations; ++i) {
- if (rel.Parse(rel_data, &offset) == false)
+ if (!rel.Parse(rel_data, &offset))
break;
Symbol *symbol = NULL;
@@ -2684,6 +2704,7 @@ unsigned ObjectFileELF::ApplyRelocations(
}
} else {
switch (reloc_type(rel)) {
+ case R_AARCH64_ABS64:
case R_X86_64_64: {
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol) {
@@ -2692,26 +2713,34 @@ unsigned ObjectFileELF::ApplyRelocations(
uint64_t *dst = reinterpret_cast<uint64_t *>(
data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
ELFRelocation::RelocOffset64(rel));
- *dst = value + ELFRelocation::RelocAddend64(rel);
+ uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
+ memcpy(dst, &val_offset, sizeof(uint64_t));
}
break;
}
case R_X86_64_32:
- case R_X86_64_32S: {
+ case R_X86_64_32S:
+ case R_AARCH64_ABS32: {
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol) {
addr_t value = symbol->GetAddressRef().GetFileAddress();
value += ELFRelocation::RelocAddend32(rel);
- assert(
- (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||
+ if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) ||
(reloc_type(rel) == R_X86_64_32S &&
- ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)));
+ ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) ||
+ (reloc_type(rel) == R_AARCH64_ABS32 &&
+ ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
+ Log *log =
+ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
+ log->Printf("Failed to apply debug info relocations");
+ break;
+ }
uint32_t truncated_addr = (value & 0xFFFFFFFF);
DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
uint32_t *dst = reinterpret_cast<uint32_t *>(
data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
ELFRelocation::RelocOffset32(rel));
- *dst = truncated_addr;
+ memcpy(dst, &truncated_addr, sizeof(uint32_t));
}
break;
}
@@ -2735,9 +2764,8 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
if (!section_list)
return 0;
- // Section ID's are ones based.
- user_id_t symtab_id = rel_hdr->sh_link + 1;
- user_id_t debug_id = rel_hdr->sh_info + 1;
+ user_id_t symtab_id = rel_hdr->sh_link;
+ user_id_t debug_id = rel_hdr->sh_info;
const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
if (!symtab_hdr)
@@ -2975,8 +3003,7 @@ void ObjectFileELF::Dump(Stream *s) {
s->Indent();
s->PutCString("ObjectFileELF");
- ArchSpec header_arch;
- GetArchitecture(header_arch);
+ ArchSpec header_arch = GetArchitecture();
*s << ", file = '" << m_file
<< "', arch = " << header_arch.GetArchitectureName() << "\n";
@@ -3153,11 +3180,9 @@ void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
s->PutCString("==== --------------- -------- -------- -------- "
"-------- -------- ------------------------- --------\n");
- uint32_t idx = 0;
- for (ProgramHeaderCollConstIter I = m_program_headers.begin();
- I != m_program_headers.end(); ++I, ++idx) {
- s->Printf("[%2u] ", idx);
- ObjectFileELF::DumpELFProgramHeader(s, *I);
+ for (const auto &H : llvm::enumerate(m_program_headers)) {
+ s->Format("[{0,2}] ", H.index());
+ ObjectFileELF::DumpELFProgramHeader(s, H.value());
s->EOL();
}
}
@@ -3264,9 +3289,9 @@ void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
}
}
-bool ObjectFileELF::GetArchitecture(ArchSpec &arch) {
+ArchSpec ObjectFileELF::GetArchitecture() {
if (!ParseHeader())
- return false;
+ return ArchSpec();
if (m_section_headers.empty()) {
// Allow elf notes to be parsed which may affect the detected architecture.
@@ -3277,23 +3302,17 @@ bool ObjectFileELF::GetArchitecture(ArchSpec &arch) {
m_arch_spec.TripleOSIsUnspecifiedUnknown()) {
// Core files don't have section headers yet they have PT_NOTE program
// headers that might shed more light on the architecture
- if (ParseProgramHeaders()) {
- for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) {
- const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i);
- if (header && header->p_type == PT_NOTE && header->p_offset != 0 &&
- header->p_filesz > 0) {
- DataExtractor data;
- if (data.SetData(m_data, header->p_offset, header->p_filesz) ==
- header->p_filesz) {
- lldb_private::UUID uuid;
- RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
- }
- }
+ for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
+ if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
+ continue;
+ DataExtractor data;
+ if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
+ UUID uuid;
+ RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
}
}
}
- arch = m_arch_spec;
- return true;
+ return m_arch_spec;
}
ObjectFile::Type ObjectFileELF::CalculateType() {
@@ -3385,8 +3404,6 @@ size_t ObjectFileELF::ReadSectionData(Section *section,
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;
@@ -3397,29 +3414,43 @@ size_t ObjectFileELF::ReadSectionData(Section *section,
size_t(section_data.GetByteSize())},
GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
if (!Decompressor) {
- LLDB_LOG_ERROR(log, Decompressor.takeError(),
- "Unable to initialize decompressor for section {0}",
- section->GetName());
- return result;
+ GetModule()->ReportWarning(
+ "Unable to initialize decompressor for section '%s': %s",
+ section->GetName().GetCString(),
+ llvm::toString(Decompressor.takeError()).c_str());
+ section_data.Clear();
+ return 0;
}
+
auto buffer_sp =
std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
- if (auto Error = Decompressor->decompress(
+ if (auto error = Decompressor->decompress(
{reinterpret_cast<char *>(buffer_sp->GetBytes()),
size_t(buffer_sp->GetByteSize())})) {
- LLDB_LOG_ERROR(log, std::move(Error), "Decompression of section {0} failed",
- section->GetName());
- return result;
+ GetModule()->ReportWarning(
+ "Decompression of section '%s' failed: %s",
+ section->GetName().GetCString(),
+ llvm::toString(std::move(error)).c_str());
+ section_data.Clear();
+ return 0;
}
+
section_data.SetData(buffer_sp);
return buffer_sp->GetByteSize();
}
+llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
+ ParseProgramHeaders();
+ return m_program_headers;
+}
+
+DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) {
+ return DataExtractor(m_data, H.p_offset, H.p_filesz);
+}
+
bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
- size_t header_count = ParseProgramHeaders();
- for (size_t i = 1; i <= header_count; ++i) {
- auto header = GetProgramHeaderByIndex(i);
- if (header->p_paddr != 0)
+ for (const ELFProgramHeader &H : ProgramHeaders()) {
+ if (H.p_paddr != 0)
return true;
}
return false;
@@ -3430,19 +3461,17 @@ ObjectFileELF::GetLoadableData(Target &target) {
// Create a list of loadable data from loadable segments, using physical
// addresses if they aren't all null
std::vector<LoadableData> loadables;
- size_t header_count = ParseProgramHeaders();
bool should_use_paddr = AnySegmentHasPhysicalAddress();
- for (size_t i = 1; i <= header_count; ++i) {
+ for (const ELFProgramHeader &H : ProgramHeaders()) {
LoadableData loadable;
- auto header = GetProgramHeaderByIndex(i);
- if (header->p_type != llvm::ELF::PT_LOAD)
+ if (H.p_type != llvm::ELF::PT_LOAD)
continue;
- loadable.Dest = should_use_paddr ? header->p_paddr : header->p_vaddr;
+ loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
if (loadable.Dest == LLDB_INVALID_ADDRESS)
continue;
- if (header->p_filesz == 0)
+ if (H.p_filesz == 0)
continue;
- auto segment_data = GetSegmentDataByIndex(i);
+ auto segment_data = GetSegmentData(H);
loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
segment_data.GetByteSize());
loadables.push_back(loadable);
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 2664595fd81d..08fd5bdc60a9 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -10,10 +10,8 @@
#ifndef liblldb_ObjectFileELF_h_
#define liblldb_ObjectFileELF_h_
-// C Includes
#include <stdint.h>
-// C++ Includes
#include <vector>
#include "lldb/Symbol/ObjectFile.h"
@@ -123,7 +121,7 @@ public:
void Dump(lldb_private::Stream *s) override;
- bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+ lldb_private::ArchSpec GetArchitecture() override;
bool GetUUID(lldb_private::UUID *uuid) override;
@@ -136,6 +134,8 @@ public:
lldb_private::Address GetEntryPointAddress() override;
+ lldb_private::Address GetBaseAddress() override;
+
ObjectFile::Type CalculateType() override;
ObjectFile::Strata CalculateStrata() override;
@@ -147,14 +147,8 @@ public:
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();
-
- // Returns the program header with the given index.
- const elf::ELFProgramHeader *GetProgramHeaderByIndex(lldb::user_id_t id);
-
- // Returns segment data for the given index.
- lldb_private::DataExtractor GetSegmentDataByIndex(lldb::user_id_t id);
+ llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders();
+ lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H);
llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
@@ -176,8 +170,6 @@ private:
const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;
- typedef ProgramHeaderColl::iterator ProgramHeaderCollIter;
- typedef ProgramHeaderColl::const_iterator ProgramHeaderCollConstIter;
struct ELFSectionHeaderInfo : public elf::ELFSectionHeader {
lldb_private::ConstString section_name;
@@ -230,10 +222,10 @@ private:
/// The address class for each symbol in the elf file
FileAddressToAddressClassMap m_address_class_map;
- /// Returns a 1 based index of the given section header.
+ /// Returns the index of the given section header.
size_t SectionIndex(const SectionHeaderCollIter &I);
- /// Returns a 1 based index of the given section header.
+ /// Returns the index of the given section header.
size_t SectionIndex(const SectionHeaderCollConstIter &I) const;
// Parses the ELF program headers.
@@ -248,14 +240,16 @@ private:
/// Parses all section headers present in this object file and populates
/// m_program_headers. This method will compute the header list only once.
- /// Returns the number of headers parsed.
- size_t ParseProgramHeaders();
+ /// Returns true iff the headers have been successfully parsed.
+ bool ParseProgramHeaders();
/// Parses all section headers present in this object file and populates
/// m_section_headers. This method will compute the header list only once.
/// Returns the number of headers parsed.
size_t ParseSectionHeaders();
+ lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const;
+
static void ParseARMAttributes(lldb_private::DataExtractor &data,
uint64_t length,
lldb_private::ArchSpec &arch_spec);
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index af040322ec52..cfe61992be0d 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -153,8 +153,7 @@ void ObjectFileJIT::Dump(Stream *s) {
s->Indent();
s->PutCString("ObjectFileJIT");
- ArchSpec arch;
- if (GetArchitecture(arch))
+ if (ArchSpec arch = GetArchitecture())
*s << ", arch = " << arch.GetArchitectureName();
s->EOL();
@@ -184,17 +183,16 @@ lldb_private::Address ObjectFileJIT::GetEntryPointAddress() {
return Address();
}
-lldb_private::Address ObjectFileJIT::GetHeaderAddress() { return Address(); }
+lldb_private::Address ObjectFileJIT::GetBaseAddress() { return Address(); }
ObjectFile::Type ObjectFileJIT::CalculateType() { return eTypeJIT; }
ObjectFile::Strata ObjectFileJIT::CalculateStrata() { return eStrataJIT; }
-bool ObjectFileJIT::GetArchitecture(ArchSpec &arch) {
- ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
- if (delegate_sp)
- return delegate_sp->GetArchitecture(arch);
- return false;
+ArchSpec ObjectFileJIT::GetArchitecture() {
+ if (ObjectFileJITDelegateSP delegate_sp = m_delegate_wp.lock())
+ return delegate_sp->GetArchitecture();
+ return ArchSpec();
}
//------------------------------------------------------------------
@@ -218,7 +216,7 @@ bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
// that size on disk (to avoid __PAGEZERO) and load them
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp && section_sp->GetFileSize() > 0 &&
- section_sp->IsThreadSpecific() == false) {
+ !section_sp->IsThreadSpecific()) {
if (target.GetSectionLoadList().SetSectionLoadAddress(
section_sp, section_sp->GetFileAddress() + value))
++num_loaded_sections;
diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index c964906a5e8e..3d9e4748d3df 100644
--- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ObjectFileJIT_h_
#define liblldb_ObjectFileJIT_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -77,7 +73,7 @@ public:
void Dump(lldb_private::Stream *s) override;
- bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+ lldb_private::ArchSpec GetArchitecture() override;
bool GetUUID(lldb_private::UUID *uuid) override;
@@ -93,7 +89,7 @@ public:
lldb_private::Address GetEntryPointAddress() override;
- lldb_private::Address GetHeaderAddress() override;
+ lldb_private::Address GetBaseAddress() override;
ObjectFile::Type CalculateType() override;
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 91e7f3353270..06908fecf984 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
-// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
@@ -23,7 +19,6 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RangeMap.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/Host.h"
@@ -41,12 +36,13 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
-#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Host/SafeMachO.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -919,12 +915,10 @@ size_t ObjectFileMachO::GetModuleSpecifications(
spec.SetObjectOffset(file_offset);
spec.SetObjectSize(length);
- if (GetArchitecture(header, data, data_offset,
- spec.GetArchitecture())) {
- if (spec.GetArchitecture().IsValid()) {
- GetUUID(header, data, data_offset, spec.GetUUID());
- specs.Append(spec);
- }
+ spec.GetArchitecture() = GetArchitecture(header, data, data_offset);
+ if (spec.GetArchitecture().IsValid()) {
+ GetUUID(header, data, data_offset, spec.GetUUID());
+ specs.Append(spec);
}
}
}
@@ -962,6 +956,11 @@ const ConstString &ObjectFileMachO::GetSegmentNameLINKEDIT() {
return g_section_name_LINKEDIT;
}
+const ConstString &ObjectFileMachO::GetSegmentNameDWARF() {
+ static ConstString g_section_name("__DWARF");
+ return g_section_name;
+}
+
const ConstString &ObjectFileMachO::GetSectionNameEHFrame() {
static ConstString g_section_name_eh_frame("__eh_frame");
return g_section_name_eh_frame;
@@ -1102,9 +1101,7 @@ bool ObjectFileMachO::ParseHeader() {
if (can_parse) {
m_data.GetU32(&offset, &m_header.cputype, 6);
- ArchSpec mach_arch;
-
- if (GetArchitecture(mach_arch)) {
+ if (ArchSpec mach_arch = GetArchitecture()) {
// Check if the module has a required architecture
const ArchSpec &module_arch = module_sp->GetArchitecture();
if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
@@ -1191,21 +1188,28 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) {
case eSectionTypeDebug:
case eSectionTypeDWARFDebugAbbrev:
+ case eSectionTypeDWARFDebugAbbrevDwo:
case eSectionTypeDWARFDebugAddr:
case eSectionTypeDWARFDebugAranges:
case eSectionTypeDWARFDebugCuIndex:
case eSectionTypeDWARFDebugFrame:
case eSectionTypeDWARFDebugInfo:
+ case eSectionTypeDWARFDebugInfoDwo:
case eSectionTypeDWARFDebugLine:
+ case eSectionTypeDWARFDebugLineStr:
case eSectionTypeDWARFDebugLoc:
+ case eSectionTypeDWARFDebugLocLists:
case eSectionTypeDWARFDebugMacInfo:
case eSectionTypeDWARFDebugMacro:
case eSectionTypeDWARFDebugNames:
case eSectionTypeDWARFDebugPubNames:
case eSectionTypeDWARFDebugPubTypes:
case eSectionTypeDWARFDebugRanges:
+ case eSectionTypeDWARFDebugRngLists:
case eSectionTypeDWARFDebugStr:
+ case eSectionTypeDWARFDebugStrDwo:
case eSectionTypeDWARFDebugStrOffsets:
+ case eSectionTypeDWARFDebugStrOffsetsDwo:
case eSectionTypeDWARFDebugTypes:
case eSectionTypeDWARFAppleNames:
case eSectionTypeDWARFAppleTypes:
@@ -1455,6 +1459,7 @@ static lldb::SectionType GetSectionType(uint32_t flags,
static ConstString g_sect_name_dwarf_debug_info("__debug_info");
static ConstString g_sect_name_dwarf_debug_line("__debug_line");
static ConstString g_sect_name_dwarf_debug_loc("__debug_loc");
+ static ConstString g_sect_name_dwarf_debug_loclists("__debug_loclists");
static ConstString g_sect_name_dwarf_debug_macinfo("__debug_macinfo");
static ConstString g_sect_name_dwarf_debug_names("__debug_names");
static ConstString g_sect_name_dwarf_debug_pubnames("__debug_pubnames");
@@ -1484,6 +1489,8 @@ static lldb::SectionType GetSectionType(uint32_t flags,
return eSectionTypeDWARFDebugLine;
if (section_name == g_sect_name_dwarf_debug_loc)
return eSectionTypeDWARFDebugLoc;
+ if (section_name == g_sect_name_dwarf_debug_loclists)
+ return eSectionTypeDWARFDebugLocLists;
if (section_name == g_sect_name_dwarf_debug_macinfo)
return eSectionTypeDWARFDebugMacInfo;
if (section_name == g_sect_name_dwarf_debug_names)
@@ -1493,7 +1500,7 @@ static lldb::SectionType GetSectionType(uint32_t flags,
if (section_name == g_sect_name_dwarf_debug_pubtypes)
return eSectionTypeDWARFDebugPubTypes;
if (section_name == g_sect_name_dwarf_debug_ranges)
- return eSectionTypeDWARFDebugRanges;
+ return eSectionTypeDWARFDebugRanges;
if (section_name == g_sect_name_dwarf_debug_str)
return eSectionTypeDWARFDebugStr;
if (section_name == g_sect_name_dwarf_debug_types)
@@ -1668,7 +1675,7 @@ void ObjectFileMachO::ProcessSegmentCommand(const load_command &load_cmd_,
} else if (unified_section_sp) {
if (is_dsym && unified_section_sp->GetFileAddress() != load_cmd.vmaddr) {
// Check to see if the module was read from memory?
- if (module_sp->GetObjectFile()->GetHeaderAddress().IsValid()) {
+ if (module_sp->GetObjectFile()->GetBaseAddress().IsValid()) {
// We have a module that is in memory and needs to have its file
// address adjusted. We need to do this because when we load a file
// from memory, its addresses will be slid already, yet the addresses
@@ -2177,7 +2184,7 @@ size_t ObjectFileMachO::ParseSymtab() {
uint32_t name_offset = cmd_offset + m_data.GetU32(&offset);
const char *path = m_data.PeekCStr(name_offset);
if (path) {
- FileSpec file_spec(path, false);
+ FileSpec file_spec(path);
// Strip the path if there is @rpath, @executable, etc so we just use
// the basename
if (path[0] == '@')
@@ -2331,14 +2338,6 @@ size_t ObjectFileMachO::ParseSymtab() {
if (nlist_data_sp)
nlist_data.SetData(nlist_data_sp, 0,
nlist_data_sp->GetByteSize());
- // Load strings individually from memory when loading from memory
- // since shared cache string tables contain strings for all symbols
- // from all shared cached libraries DataBufferSP strtab_data_sp
- // (ReadMemory (process_sp, strtab_addr,
- // strtab_data_byte_size));
- // if (strtab_data_sp)
- // strtab_data.SetData (strtab_data_sp, 0,
- // strtab_data_sp->GetByteSize());
if (m_dysymtab.nindirectsyms != 0) {
const addr_t indirect_syms_addr = linkedit_load_addr +
m_dysymtab.indirectsymoff -
@@ -2350,8 +2349,25 @@ size_t ObjectFileMachO::ParseSymtab() {
indirect_symbol_index_data.SetData(
indirect_syms_data_sp, 0,
indirect_syms_data_sp->GetByteSize());
+ // If this binary is outside the shared cache,
+ // cache the string table.
+ // Binaries in the shared cache all share a giant string table, and
+ // we can't share the string tables across multiple ObjectFileMachO's,
+ // so we'd end up re-reading this mega-strtab for every binary
+ // in the shared cache - it would be a big perf problem.
+ // For binaries outside the shared cache, it's faster to read the
+ // entire strtab at once instead of piece-by-piece as we process
+ // the nlist records.
+ if ((m_header.flags & 0x80000000u) == 0) {
+ DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr,
+ strtab_data_byte_size));
+ if (strtab_data_sp) {
+ strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ }
+ }
}
- } else if (memory_module_load_level >=
+ }
+ if (memory_module_load_level >=
eMemoryModuleLoadLevelPartial) {
if (function_starts_load_command.cmd) {
const addr_t func_start_addr =
@@ -2621,7 +2637,7 @@ size_t ObjectFileMachO::ParseSymtab() {
// shared cache UUID in the development or non-development shared caches
// on disk.
if (process_shared_cache_uuid.IsValid()) {
- if (dsc_development_filespec.Exists()) {
+ if (FileSystem::Instance().Exists(dsc_development_filespec)) {
UUID dsc_development_uuid = GetSharedCacheUUID(
dsc_development_filespec, byte_order, addr_byte_size);
if (dsc_development_uuid.IsValid() &&
@@ -2630,7 +2646,8 @@ size_t ObjectFileMachO::ParseSymtab() {
dsc_uuid = dsc_development_uuid;
}
}
- if (!dsc_uuid.IsValid() && dsc_nondevelopment_filespec.Exists()) {
+ if (!dsc_uuid.IsValid() &&
+ FileSystem::Instance().Exists(dsc_nondevelopment_filespec)) {
UUID dsc_nondevelopment_uuid = GetSharedCacheUUID(
dsc_nondevelopment_filespec, byte_order, addr_byte_size);
if (dsc_nondevelopment_uuid.IsValid() &&
@@ -2643,8 +2660,8 @@ size_t ObjectFileMachO::ParseSymtab() {
// Failing a UUID match, prefer the development dyld_shared cache if both
// are present.
- if (!dsc_filespec.Exists()) {
- if (dsc_development_filespec.Exists()) {
+ if (!FileSystem::Instance().Exists(dsc_filespec)) {
+ if (FileSystem::Instance().Exists(dsc_development_filespec)) {
dsc_filespec = dsc_development_filespec;
} else {
dsc_filespec = dsc_nondevelopment_filespec;
@@ -3052,11 +3069,11 @@ size_t ObjectFileMachO::ParseSymtab() {
// file so you end up with a path that looks
// like "/tmp/src//tmp/src/"
FileSpec so_dir(so_path, false);
- if (!so_dir.Exists()) {
+ if (!FileSystem::Instance().Exists(so_dir)) {
so_dir.SetFile(
&full_so_path[double_slash_pos + 1],
false);
- if (so_dir.Exists()) {
+ if (FileSystem::Instance().Exists(so_dir)) {
// Trim off the incorrect path
full_so_path.erase(0,
double_slash_pos + 1);
@@ -4001,11 +4018,11 @@ size_t ObjectFileMachO::ParseSymtab() {
// string in the DW_AT_comp_dir, and the second is the
// directory for the source file so you end up with a path
// that looks like "/tmp/src//tmp/src/"
- FileSpec so_dir(so_path, false);
- if (!so_dir.Exists()) {
- so_dir.SetFile(&full_so_path[double_slash_pos + 1], false,
+ FileSpec so_dir(so_path);
+ if (!FileSystem::Instance().Exists(so_dir)) {
+ so_dir.SetFile(&full_so_path[double_slash_pos + 1],
FileSpec::Style::native);
- if (so_dir.Exists()) {
+ if (FileSystem::Instance().Exists(so_dir)) {
// Trim off the incorrect path
full_so_path.erase(0, double_slash_pos + 1);
}
@@ -4453,7 +4470,7 @@ size_t ObjectFileMachO::ParseSymtab() {
symbol_value -= section_file_addr;
}
- if (is_debug == false) {
+ if (!is_debug) {
if (type == eSymbolTypeCode) {
// See if we can find a N_FUN entry for any code symbols. If we
// do find a match, and the name matches, then we can merge the
@@ -4600,7 +4617,7 @@ size_t ObjectFileMachO::ParseSymtab() {
if (function_starts_count > 0) {
uint32_t num_synthetic_function_symbols = 0;
for (i = 0; i < function_starts_count; ++i) {
- if (function_starts.GetEntryRef(i).data == false)
+ if (!function_starts.GetEntryRef(i).data)
++num_synthetic_function_symbols;
}
@@ -4612,7 +4629,7 @@ size_t ObjectFileMachO::ParseSymtab() {
for (i = 0; i < function_starts_count; ++i) {
const FunctionStarts::Entry *func_start_entry =
function_starts.GetEntryAtIndex(i);
- if (func_start_entry->data == false) {
+ if (!func_start_entry->data) {
addr_t symbol_file_addr = func_start_entry->addr;
uint32_t symbol_flags = 0;
if (is_arm) {
@@ -4817,8 +4834,7 @@ void ObjectFileMachO::Dump(Stream *s) {
else
s->PutCString("ObjectFileMachO32");
- ArchSpec header_arch;
- GetArchitecture(header_arch);
+ ArchSpec header_arch = GetArchitecture();
*s << ", file = '" << m_file
<< "', triple = " << header_arch.GetTriple().getTriple() << "\n";
@@ -4869,25 +4885,83 @@ bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
return false;
}
-static const char *GetOSName(uint32_t cmd) {
+static llvm::StringRef GetOSName(uint32_t cmd) {
switch (cmd) {
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
- return "ios";
+ return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
case llvm::MachO::LC_VERSION_MIN_MACOSX:
- return "macosx";
+ return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
case llvm::MachO::LC_VERSION_MIN_TVOS:
- return "tvos";
+ return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
case llvm::MachO::LC_VERSION_MIN_WATCHOS:
- return "watchos";
+ return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
default:
llvm_unreachable("unexpected LC_VERSION load command");
}
}
-bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset,
- ArchSpec &arch) {
+namespace {
+ struct OSEnv {
+ llvm::StringRef os_type;
+ llvm::StringRef environment;
+ OSEnv(uint32_t cmd) {
+ switch (cmd) {
+ case PLATFORM_MACOS:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
+ return;
+ case PLATFORM_IOS:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
+ return;
+ case PLATFORM_TVOS:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
+ return;
+ case PLATFORM_WATCHOS:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
+ return;
+// NEED_BRIDGEOS_TRIPLE case PLATFORM_BRIDGEOS:
+// NEED_BRIDGEOS_TRIPLE os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
+// NEED_BRIDGEOS_TRIPLE return;
+#if defined (PLATFORM_IOSSIMULATOR) && defined (PLATFORM_TVOSSIMULATOR) && defined (PLATFORM_WATCHOSSIMULATOR)
+ case PLATFORM_IOSSIMULATOR:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
+ environment =
+ llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
+ return;
+ case PLATFORM_TVOSSIMULATOR:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
+ environment =
+ llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
+ return;
+ case PLATFORM_WATCHOSSIMULATOR:
+ os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
+ environment =
+ llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
+ return;
+#endif
+ default: {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS |
+ LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf("unsupported platform in LC_BUILD_VERSION");
+ }
+ }
+ }
+ };
+
+ struct MinOS {
+ uint32_t major_version, minor_version, patch_version;
+ MinOS(uint32_t version)
+ : major_version(version >> 16),
+ minor_version((version >> 8) & 0xffu),
+ patch_version(version & 0xffu) {}
+ };
+} // namespace
+
+ArchSpec
+ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t lc_offset) {
+ ArchSpec arch;
arch.SetArchitecture(eArchTypeMachO, header.cputype, header.cpusubtype);
if (arch.IsValid()) {
@@ -4912,39 +4986,37 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
triple.setVendor(llvm::Triple::UnknownVendor);
triple.setVendorName(llvm::StringRef());
}
- return true;
+ return arch;
} else {
struct load_command load_cmd;
+ llvm::SmallString<16> os_name;
+ llvm::raw_svector_ostream os(os_name);
+ // See if there is an LC_VERSION_MIN_* load command that can give
+ // us the OS type.
lldb::offset_t offset = lc_offset;
for (uint32_t i = 0; i < header.ncmds; ++i) {
const lldb::offset_t cmd_offset = offset;
if (data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
- uint32_t major, minor, patch;
struct version_min_command version_min;
-
- llvm::SmallString<16> os_name;
- llvm::raw_svector_ostream os(os_name);
-
switch (load_cmd.cmd) {
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
case llvm::MachO::LC_VERSION_MIN_MACOSX:
case llvm::MachO::LC_VERSION_MIN_TVOS:
- case llvm::MachO::LC_VERSION_MIN_WATCHOS:
+ case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
if (load_cmd.cmdsize != sizeof(version_min))
break;
- data.ExtractBytes(cmd_offset,
- sizeof(version_min), data.GetByteOrder(),
- &version_min);
- major = version_min.version >> 16;
- minor = (version_min.version >> 8) & 0xffu;
- patch = version_min.version & 0xffu;
- os << GetOSName(load_cmd.cmd) << major << '.' << minor << '.'
- << patch;
+ if (data.ExtractBytes(cmd_offset, sizeof(version_min),
+ data.GetByteOrder(), &version_min) == 0)
+ break;
+ MinOS min_os(version_min.version);
+ os << GetOSName(load_cmd.cmd) << min_os.major_version << '.'
+ << min_os.minor_version << '.' << min_os.patch_version;
triple.setOSName(os.str());
- return true;
+ return arch;
+ }
default:
break;
}
@@ -4952,6 +5024,39 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
offset = cmd_offset + load_cmd.cmdsize;
}
+ // See if there is an LC_BUILD_VERSION load command that can give
+ // us the OS type.
+
+ offset = lc_offset;
+ for (uint32_t i = 0; i < header.ncmds; ++i) {
+ const lldb::offset_t cmd_offset = offset;
+ if (data.GetU32(&offset, &load_cmd, 2) == NULL)
+ break;
+ do {
+ if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
+ struct build_version_command build_version;
+ if (load_cmd.cmdsize < sizeof(build_version)) {
+ // Malformed load command.
+ break;
+ }
+ if (data.ExtractBytes(cmd_offset, sizeof(build_version),
+ data.GetByteOrder(), &build_version) == 0)
+ break;
+ MinOS min_os(build_version.minos);
+ OSEnv os_env(build_version.platform);
+ if (os_env.os_type.empty())
+ break;
+ os << os_env.os_type << min_os.major_version << '.'
+ << min_os.minor_version << '.' << min_os.patch_version;
+ triple.setOSName(os.str());
+ if (!os_env.environment.empty())
+ triple.setEnvironmentName(os_env.environment);
+ return arch;
+ }
+ } while (0);
+ offset = cmd_offset + load_cmd.cmdsize;
+ }
+
if (header.filetype != MH_KEXT_BUNDLE) {
// We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
// so lets not say our Vendor is Apple, leave it as an unspecified
@@ -4961,7 +5066,7 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
}
}
}
- return arch.IsValid();
+ return arch;
}
bool ObjectFileMachO::GetUUID(lldb_private::UUID *uuid) {
@@ -4984,9 +5089,6 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
std::vector<std::string> rpath_paths;
std::vector<std::string> rpath_relative_paths;
std::vector<std::string> at_exec_relative_paths;
- const bool resolve_path = false; // Don't resolve the dependent file paths
- // since they may not reside on this
- // system
uint32_t i;
for (i = 0; i < m_header.ncmds; ++i) {
const uint32_t cmd_offset = offset;
@@ -5015,7 +5117,7 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
at_exec_relative_paths.push_back(path
+ strlen("@executable_path"));
} else {
- FileSpec file_spec(path, resolve_path);
+ FileSpec file_spec(path);
if (files.AppendIfUnique(file_spec))
count++;
}
@@ -5030,8 +5132,8 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
}
FileSpec this_file_spec(m_file);
- this_file_spec.ResolvePath();
-
+ FileSystem::Instance().Resolve(this_file_spec);
+
if (!rpath_paths.empty()) {
// Fixup all LC_RPATH values to be absolute paths
std::string loader_path("@loader_path");
@@ -5052,8 +5154,10 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
path += rpath_relative_path;
// It is OK to resolve this path because we must find a file on disk
// for us to accept it anyway if it is rpath relative.
- FileSpec file_spec(path, true);
- if (file_spec.Exists() && files.AppendIfUnique(file_spec)) {
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ if (FileSystem::Instance().Exists(file_spec) &&
+ files.AppendIfUnique(file_spec)) {
count++;
break;
}
@@ -5070,7 +5174,8 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) {
for (const auto &at_exec_relative_path : at_exec_relative_paths) {
FileSpec file_spec =
exec_dir.CopyByAppendingPathComponent(at_exec_relative_path);
- if (file_spec.Exists() && files.AppendIfUnique(file_spec))
+ if (FileSystem::Instance().Exists(file_spec) &&
+ files.AppendIfUnique(file_spec))
count++;
}
}
@@ -5235,7 +5340,7 @@ lldb_private::Address ObjectFileMachO::GetEntryPointAddress() {
return m_entry_point_address;
}
-lldb_private::Address ObjectFileMachO::GetHeaderAddress() {
+lldb_private::Address ObjectFileMachO::GetBaseAddress() {
lldb_private::Address header_addr;
SectionList *section_list = GetSectionList();
if (section_list) {
@@ -5583,14 +5688,16 @@ llvm::VersionTuple ObjectFileMachO::GetVersion() {
return llvm::VersionTuple();
}
-bool ObjectFileMachO::GetArchitecture(ArchSpec &arch) {
+ArchSpec ObjectFileMachO::GetArchitecture() {
ModuleSP module_sp(GetModule());
+ ArchSpec arch;
if (module_sp) {
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+
return GetArchitecture(m_header, m_data,
- MachHeaderSizeFromMagic(m_header.magic), arch);
+ MachHeaderSizeFromMagic(m_header.magic));
}
- return false;
+ return arch;
}
void ObjectFileMachO::GetProcessSharedCacheUUID(Process *process, addr_t &base_addr, UUID &uuid) {
@@ -5716,8 +5823,30 @@ llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
break;
}
+ }
+ } else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
+ // struct build_version_command {
+ // uint32_t cmd; /* LC_BUILD_VERSION */
+ // uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
+ // /* ntools * sizeof(struct build_tool_version) */
+ // uint32_t platform; /* platform */
+ // uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+ // uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+ // uint32_t ntools; /* number of tool entries following this */
+ // };
+
+ offset += 4; // skip platform
+ uint32_t minos = m_data.GetU32(&offset);
+
+ const uint32_t xxxx = minos >> 16;
+ const uint32_t yy = (minos >> 8) & 0xffu;
+ const uint32_t zz = minos & 0xffu;
+ if (xxxx) {
+ m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
+ break;
}
}
+
offset = load_cmd_offset + lc.cmdsize;
}
@@ -5735,7 +5864,7 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
if (m_sdk_versions.empty()) {
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
bool success = false;
- for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i) {
+ for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
const lldb::offset_t load_cmd_offset = offset;
version_min_command lc;
@@ -5764,7 +5893,46 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
offset = load_cmd_offset + lc.cmdsize;
}
- if (success == false) {
+ if (!success) {
+ offset = MachHeaderSizeFromMagic(m_header.magic);
+ for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
+ const lldb::offset_t load_cmd_offset = offset;
+
+ version_min_command lc;
+ if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
+ break;
+ if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
+ // struct build_version_command {
+ // uint32_t cmd; /* LC_BUILD_VERSION */
+ // uint32_t cmdsize; /* sizeof(struct
+ // build_version_command) plus */
+ // /* ntools * sizeof(struct
+ // build_tool_version) */
+ // uint32_t platform; /* platform */
+ // uint32_t minos; /* X.Y.Z is encoded in nibbles
+ // xxxx.yy.zz */ uint32_t sdk; /* X.Y.Z is encoded
+ // in nibbles xxxx.yy.zz */ uint32_t ntools; /* number
+ // of tool entries following this */
+ // };
+
+ offset += 4; // skip platform
+ uint32_t minos = m_data.GetU32(&offset);
+
+ const uint32_t xxxx = minos >> 16;
+ const uint32_t yy = (minos >> 8) & 0xffu;
+ const uint32_t zz = minos & 0xffu;
+ if (xxxx) {
+ m_sdk_versions.push_back(xxxx);
+ m_sdk_versions.push_back(yy);
+ m_sdk_versions.push_back(zz);
+ success = true;
+ }
+ }
+ offset = load_cmd_offset + lc.cmdsize;
+ }
+ }
+
+ if (!success) {
// Push an invalid value so we don't try to find
// the version # again on the next call to this
// method.
@@ -5814,52 +5982,52 @@ Section *ObjectFileMachO::GetMachHeaderSection() {
// the mach-o file which can be subtracted from the vmaddr of the other
// segments found in memory and added to the load address
ModuleSP module_sp = GetModule();
- if (module_sp) {
- SectionList *section_list = GetSectionList();
- if (section_list) {
- lldb::addr_t mach_base_file_addr = LLDB_INVALID_ADDRESS;
- const size_t num_sections = section_list->GetSize();
-
- for (size_t sect_idx = 0; sect_idx < num_sections &&
- mach_base_file_addr == LLDB_INVALID_ADDRESS;
- ++sect_idx) {
- Section *section = section_list->GetSectionAtIndex(sect_idx).get();
- if (section && section->GetFileSize() > 0 &&
- section->GetFileOffset() == 0 &&
- section->IsThreadSpecific() == false &&
- module_sp.get() == section->GetModule().get()) {
- return section;
- }
- }
- }
+ if (!module_sp)
+ return nullptr;
+ SectionList *section_list = GetSectionList();
+ if (!section_list)
+ return nullptr;
+ const size_t num_sections = section_list->GetSize();
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
+ Section *section = section_list->GetSectionAtIndex(sect_idx).get();
+ if (section->GetFileOffset() == 0 && SectionIsLoadable(section))
+ return section;
}
return nullptr;
}
+bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
+ if (!section)
+ return false;
+ const bool is_dsym = (m_header.filetype == MH_DSYM);
+ if (section->GetFileSize() == 0 && !is_dsym)
+ return false;
+ if (section->IsThreadSpecific())
+ return false;
+ if (GetModule().get() != section->GetModule().get())
+ return false;
+ // Be careful with __LINKEDIT and __DWARF segments
+ if (section->GetName() == GetSegmentNameLINKEDIT() ||
+ section->GetName() == GetSegmentNameDWARF()) {
+ // Only map __LINKEDIT and __DWARF if we have an in memory image and
+ // this isn't a kernel binary like a kext or mach_kernel.
+ const bool is_memory_image = (bool)m_process_wp.lock();
+ const Strata strata = GetStrata();
+ if (is_memory_image == false || strata == eStrataKernel)
+ return false;
+ }
+ return true;
+}
+
lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
- lldb::addr_t mach_header_load_address, const Section *mach_header_section,
+ lldb::addr_t header_load_address, const Section *header_section,
const Section *section) {
ModuleSP module_sp = GetModule();
- if (module_sp && mach_header_section && section &&
- mach_header_load_address != LLDB_INVALID_ADDRESS) {
- lldb::addr_t mach_header_file_addr = mach_header_section->GetFileAddress();
- if (mach_header_file_addr != LLDB_INVALID_ADDRESS) {
- if (section && section->GetFileSize() > 0 &&
- section->IsThreadSpecific() == false &&
- module_sp.get() == section->GetModule().get()) {
- // Ignore __LINKEDIT and __DWARF segments
- if (section->GetName() == GetSegmentNameLINKEDIT()) {
- // Only map __LINKEDIT if we have an in memory image and this isn't a
- // kernel binary like a kext or mach_kernel.
- const bool is_memory_image = (bool)m_process_wp.lock();
- const Strata strata = GetStrata();
- if (is_memory_image == false || strata == eStrataKernel)
- return LLDB_INVALID_ADDRESS;
- }
- return section->GetFileAddress() - mach_header_file_addr +
- mach_header_load_address;
- }
- }
+ if (module_sp && header_section && section &&
+ header_load_address != LLDB_INVALID_ADDRESS) {
+ lldb::addr_t file_addr = header_section->GetFileAddress();
+ if (file_addr != LLDB_INVALID_ADDRESS && SectionIsLoadable(section))
+ return section->GetFileAddress() - file_addr + header_load_address;
}
return LLDB_INVALID_ADDRESS;
}
@@ -5879,22 +6047,10 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
// Iterate through the object file sections to find all of the
// sections that size on disk (to avoid __PAGEZERO) and load them
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
- if (section_sp && section_sp->GetFileSize() > 0 &&
- section_sp->IsThreadSpecific() == false &&
- module_sp.get() == section_sp->GetModule().get()) {
- // Ignore __LINKEDIT and __DWARF segments
- if (section_sp->GetName() == GetSegmentNameLINKEDIT()) {
- // Only map __LINKEDIT if we have an in memory image and this
- // isn't a kernel binary like a kext or mach_kernel.
- const bool is_memory_image = (bool)m_process_wp.lock();
- const Strata strata = GetStrata();
- if (is_memory_image == false || strata == eStrataKernel)
- continue;
- }
+ if (SectionIsLoadable(section_sp.get()))
if (target.GetSectionLoadList().SetSectionLoadAddress(
section_sp, section_sp->GetFileAddress() + value))
++num_loaded_sections;
- }
}
} else {
// "value" is the new base address of the mach_header, adjust each
@@ -5933,6 +6089,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
target_triple.getOS() == llvm::Triple::IOS ||
target_triple.getOS() == llvm::Triple::WatchOS ||
target_triple.getOS() == llvm::Triple::TvOS)) {
+ // NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS)) {
bool make_core = false;
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -6161,10 +6318,10 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
File core_file;
std::string core_file_path(outfile.GetPath());
- error = core_file.Open(core_file_path.c_str(),
- File::eOpenOptionWrite |
- File::eOpenOptionTruncate |
- File::eOpenOptionCanCreate);
+ error = FileSystem::Instance().Open(core_file, outfile,
+ File::eOpenOptionWrite |
+ File::eOpenOptionTruncate |
+ File::eOpenOptionCanCreate);
if (error.Success()) {
// Read 1 page at a time
uint8_t bytes[0x1000];
diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
index be64518064b5..196abae807e9 100644
--- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
+++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
@@ -10,16 +10,12 @@
#ifndef liblldb_ObjectFileMachO_h_
#define liblldb_ObjectFileMachO_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Address.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/RangeMap.h"
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/UUID.h"
//----------------------------------------------------------------------
@@ -96,7 +92,7 @@ public:
void Dump(lldb_private::Stream *s) override;
- bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+ lldb_private::ArchSpec GetArchitecture() override;
bool GetUUID(lldb_private::UUID *uuid) override;
@@ -108,7 +104,7 @@ public:
lldb_private::Address GetEntryPointAddress() override;
- lldb_private::Address GetHeaderAddress() override;
+ lldb_private::Address GetBaseAddress() override;
uint32_t GetNumThreadContexts() override;
@@ -151,10 +147,10 @@ protected:
lldb::offset_t lc_offset, // Offset to the first load command
lldb_private::UUID &uuid);
- static bool GetArchitecture(const llvm::MachO::mach_header &header,
- const lldb_private::DataExtractor &data,
- lldb::offset_t lc_offset,
- lldb_private::ArchSpec &arch);
+ static lldb_private::ArchSpec
+ GetArchitecture(const llvm::MachO::mach_header &header,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t lc_offset);
// Intended for same-host arm device debugging where lldb needs to
// detect libraries in the shared cache and augment the nlist entries
@@ -196,6 +192,8 @@ protected:
void SanitizeSegmentCommand(llvm::MachO::segment_command_64 &seg_cmd,
uint32_t cmd_idx);
+ bool SectionIsLoadable(const lldb_private::Section *section);
+
llvm::MachO::mach_header m_header;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();
@@ -203,6 +201,7 @@ protected:
static const lldb_private::ConstString &GetSegmentNameDATA_CONST();
static const lldb_private::ConstString &GetSegmentNameOBJC();
static const lldb_private::ConstString &GetSegmentNameLINKEDIT();
+ static const lldb_private::ConstString &GetSegmentNameDWARF();
static const lldb_private::ConstString &GetSectionNameEHFrame();
llvm::MachO::dysymtab_command m_dysymtab;
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index b2967f1532ab..d18ff617521f 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -23,11 +23,14 @@
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/Object/COFFImportFile.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
@@ -86,6 +89,10 @@ ObjectFile *ObjectFilePECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
if (!objfile_ap || !objfile_ap->ParseHeader())
return nullptr;
+ // Cache coff binary.
+ if (!objfile_ap->CreateBinary())
+ return nullptr;
+
return objfile_ap.release();
}
@@ -131,9 +138,7 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
specs.Append(ModuleSpec(file, spec));
spec.SetTriple("i686-pc-windows");
specs.Append(ModuleSpec(file, spec));
- }
- else if (coff_header.machine == MachineArmNt)
- {
+ } else if (coff_header.machine == MachineArmNt) {
spec.SetTriple("arm-pc-windows");
specs.Append(ModuleSpec(file, spec));
}
@@ -168,6 +173,40 @@ lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) {
return lldb::eSymbolTypeInvalid;
}
+bool ObjectFilePECOFF::CreateBinary() {
+ if (m_owningbin)
+ return true;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+
+ auto binary = llvm::object::createBinary(m_file.GetPath());
+ if (!binary) {
+ if (log)
+ log->Printf("ObjectFilePECOFF::CreateBinary() - failed to create binary "
+ "for file (%s): %s",
+ m_file ? m_file.GetPath().c_str() : "<NULL>",
+ errorToErrorCode(binary.takeError()).message().c_str());
+ return false;
+ }
+
+ // Make sure we only handle COFF format.
+ if (!binary->getBinary()->isCOFF() &&
+ !binary->getBinary()->isCOFFImportFile())
+ return false;
+
+ m_owningbin = OWNBINType(std::move(*binary));
+ if (log)
+ log->Printf("%p ObjectFilePECOFF::CreateBinary() module = %p (%s), file = "
+ "%s, binary = %p (Bin = %p)",
+ static_cast<void *>(this),
+ static_cast<void *>(GetModule().get()),
+ GetModule()->GetSpecificationDescription().c_str(),
+ m_file ? m_file.GetPath().c_str() : "<NULL>",
+ static_cast<void *>(m_owningbin.getPointer()),
+ static_cast<void *>(m_owningbin->getBinary()));
+ return true;
+}
+
ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp,
lldb::offset_t data_offset,
@@ -176,7 +215,7 @@ ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
lldb::offset_t length)
: ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
- m_entry_point_address() {
+ m_entry_point_address(), m_deps_filespec(), m_owningbin() {
::memset(&m_dos_header, 0, sizeof(m_dos_header));
::memset(&m_coff_header, 0, sizeof(m_coff_header));
::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
@@ -188,7 +227,7 @@ ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
addr_t header_addr)
: ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
- m_entry_point_address() {
+ m_entry_point_address(), m_deps_filespec(), m_owningbin() {
::memset(&m_dos_header, 0, sizeof(m_dos_header));
::memset(&m_coff_header, 0, sizeof(m_coff_header));
::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
@@ -431,7 +470,7 @@ bool ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) {
DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
if (m_file) {
- // A bit of a hack, but we intend to write to this buffer, so we can't
+ // A bit of a hack, but we intend to write to this buffer, so we can't
// mmap it.
auto buffer_sp = MapFileData(m_file, size, offset);
return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
@@ -488,25 +527,23 @@ bool ObjectFilePECOFF::ParseSectionHeaders(
}
}
- return m_sect_headers.empty() == false;
+ return !m_sect_headers.empty();
}
-bool ObjectFilePECOFF::GetSectionName(std::string &sect_name,
- const section_header_t &sect) {
- if (sect.name[0] == '/') {
- lldb::offset_t stroff = strtoul(&sect.name[1], NULL, 10);
+llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t &sect) {
+ llvm::StringRef hdr_name(sect.name, llvm::array_lengthof(sect.name));
+ hdr_name = hdr_name.split('\0').first;
+ if (hdr_name.consume_front("/")) {
+ lldb::offset_t stroff;
+ if (!to_integer(hdr_name, stroff, 10))
+ return "";
lldb::offset_t string_file_offset =
m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
- const char *name = m_data.GetCStr(&string_file_offset);
- if (name) {
- sect_name = name;
- return true;
- }
-
- return false;
+ if (const char *name = m_data.GetCStr(&string_file_offset))
+ return name;
+ return "";
}
- sect_name = sect.name;
- return true;
+ return hdr_name;
}
//----------------------------------------------------------------------
@@ -663,144 +700,213 @@ bool ObjectFilePECOFF::IsStripped() {
}
void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
- if (!m_sections_ap.get()) {
- m_sections_ap.reset(new SectionList());
+ if (m_sections_ap)
+ return;
+ m_sections_ap.reset(new SectionList());
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ const uint32_t nsects = m_sect_headers.size();
ModuleSP module_sp(GetModule());
- if (module_sp) {
- std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
- const uint32_t nsects = m_sect_headers.size();
- ModuleSP module_sp(GetModule());
- for (uint32_t idx = 0; idx < nsects; ++idx) {
- std::string sect_name;
- GetSectionName(sect_name, m_sect_headers[idx]);
- ConstString const_sect_name(sect_name.c_str());
- static ConstString g_code_sect_name(".code");
- static ConstString g_CODE_sect_name("CODE");
- static ConstString g_data_sect_name(".data");
- static ConstString g_DATA_sect_name("DATA");
- static ConstString g_bss_sect_name(".bss");
- static ConstString g_BSS_sect_name("BSS");
- static ConstString g_debug_sect_name(".debug");
- static ConstString g_reloc_sect_name(".reloc");
- static ConstString g_stab_sect_name(".stab");
- static ConstString g_stabstr_sect_name(".stabstr");
- static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
- static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
- static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
- static ConstString g_sect_name_dwarf_debug_info(".debug_info");
- static ConstString g_sect_name_dwarf_debug_line(".debug_line");
- static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
- static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
- static ConstString g_sect_name_dwarf_debug_names(".debug_names");
- static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
- static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
- static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
- static ConstString g_sect_name_dwarf_debug_str(".debug_str");
- static ConstString g_sect_name_dwarf_debug_types(".debug_types");
- static ConstString g_sect_name_eh_frame(".eh_frame");
- static ConstString g_sect_name_go_symtab(".gosymtab");
- SectionType section_type = eSectionTypeOther;
- if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
- ((const_sect_name == g_code_sect_name) ||
- (const_sect_name == g_CODE_sect_name))) {
- section_type = eSectionTypeCode;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
- ((const_sect_name == g_data_sect_name) ||
- (const_sect_name == g_DATA_sect_name))) {
+ for (uint32_t idx = 0; idx < nsects; ++idx) {
+ ConstString const_sect_name(GetSectionName(m_sect_headers[idx]));
+ static ConstString g_code_sect_name(".code");
+ static ConstString g_CODE_sect_name("CODE");
+ static ConstString g_data_sect_name(".data");
+ static ConstString g_DATA_sect_name("DATA");
+ static ConstString g_bss_sect_name(".bss");
+ static ConstString g_BSS_sect_name("BSS");
+ static ConstString g_debug_sect_name(".debug");
+ static ConstString g_reloc_sect_name(".reloc");
+ static ConstString g_stab_sect_name(".stab");
+ static ConstString g_stabstr_sect_name(".stabstr");
+ static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
+ static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
+ static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
+ static ConstString g_sect_name_dwarf_debug_info(".debug_info");
+ static ConstString g_sect_name_dwarf_debug_line(".debug_line");
+ static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
+ static ConstString g_sect_name_dwarf_debug_loclists(".debug_loclists");
+ static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
+ static ConstString g_sect_name_dwarf_debug_names(".debug_names");
+ static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
+ static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
+ static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
+ static ConstString g_sect_name_dwarf_debug_str(".debug_str");
+ static ConstString g_sect_name_dwarf_debug_types(".debug_types");
+ static ConstString g_sect_name_eh_frame(".eh_frame");
+ static ConstString g_sect_name_go_symtab(".gosymtab");
+ SectionType section_type = eSectionTypeOther;
+ if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
+ ((const_sect_name == g_code_sect_name) ||
+ (const_sect_name == g_CODE_sect_name))) {
+ section_type = eSectionTypeCode;
+ } else if (m_sect_headers[idx].flags &
+ llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
+ ((const_sect_name == g_data_sect_name) ||
+ (const_sect_name == g_DATA_sect_name))) {
+ if (m_sect_headers[idx].size == 0 && m_sect_headers[idx].offset == 0)
+ section_type = eSectionTypeZeroFill;
+ else
section_type = eSectionTypeData;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
- ((const_sect_name == g_bss_sect_name) ||
- (const_sect_name == g_BSS_sect_name))) {
- if (m_sect_headers[idx].size == 0)
- section_type = eSectionTypeZeroFill;
- else
- section_type = eSectionTypeData;
- } else if (const_sect_name == g_debug_sect_name) {
- section_type = eSectionTypeDebug;
- } else if (const_sect_name == g_stabstr_sect_name) {
- section_type = eSectionTypeDataCString;
- } else if (const_sect_name == g_reloc_sect_name) {
- section_type = eSectionTypeOther;
- } else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)
- section_type = eSectionTypeDWARFDebugAbbrev;
- else if (const_sect_name == g_sect_name_dwarf_debug_aranges)
- section_type = eSectionTypeDWARFDebugAranges;
- else if (const_sect_name == g_sect_name_dwarf_debug_frame)
- section_type = eSectionTypeDWARFDebugFrame;
- else if (const_sect_name == g_sect_name_dwarf_debug_info)
- section_type = eSectionTypeDWARFDebugInfo;
- else if (const_sect_name == g_sect_name_dwarf_debug_line)
- section_type = eSectionTypeDWARFDebugLine;
- else if (const_sect_name == g_sect_name_dwarf_debug_loc)
- section_type = eSectionTypeDWARFDebugLoc;
- else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)
- section_type = eSectionTypeDWARFDebugMacInfo;
- else if (const_sect_name == g_sect_name_dwarf_debug_names)
- section_type = eSectionTypeDWARFDebugNames;
- else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)
- section_type = eSectionTypeDWARFDebugPubNames;
- else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)
- section_type = eSectionTypeDWARFDebugPubTypes;
- else if (const_sect_name == g_sect_name_dwarf_debug_ranges)
- section_type = eSectionTypeDWARFDebugRanges;
- else if (const_sect_name == g_sect_name_dwarf_debug_str)
- section_type = eSectionTypeDWARFDebugStr;
- else if (const_sect_name == g_sect_name_dwarf_debug_types)
- section_type = eSectionTypeDWARFDebugTypes;
- else if (const_sect_name == g_sect_name_eh_frame)
- section_type = eSectionTypeEHFrame;
- else if (const_sect_name == g_sect_name_go_symtab)
- section_type = eSectionTypeGoSymtab;
- else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) {
- section_type = eSectionTypeCode;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) {
+ } else if (m_sect_headers[idx].flags &
+ llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
+ ((const_sect_name == g_bss_sect_name) ||
+ (const_sect_name == g_BSS_sect_name))) {
+ if (m_sect_headers[idx].size == 0)
+ section_type = eSectionTypeZeroFill;
+ else
+ section_type = eSectionTypeData;
+ } else if (const_sect_name == g_debug_sect_name) {
+ section_type = eSectionTypeDebug;
+ } else if (const_sect_name == g_stabstr_sect_name) {
+ section_type = eSectionTypeDataCString;
+ } else if (const_sect_name == g_reloc_sect_name) {
+ section_type = eSectionTypeOther;
+ } else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)
+ section_type = eSectionTypeDWARFDebugAbbrev;
+ else if (const_sect_name == g_sect_name_dwarf_debug_aranges)
+ section_type = eSectionTypeDWARFDebugAranges;
+ else if (const_sect_name == g_sect_name_dwarf_debug_frame)
+ section_type = eSectionTypeDWARFDebugFrame;
+ else if (const_sect_name == g_sect_name_dwarf_debug_info)
+ section_type = eSectionTypeDWARFDebugInfo;
+ else if (const_sect_name == g_sect_name_dwarf_debug_line)
+ section_type = eSectionTypeDWARFDebugLine;
+ else if (const_sect_name == g_sect_name_dwarf_debug_loc)
+ section_type = eSectionTypeDWARFDebugLoc;
+ else if (const_sect_name == g_sect_name_dwarf_debug_loclists)
+ section_type = eSectionTypeDWARFDebugLocLists;
+ else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)
+ section_type = eSectionTypeDWARFDebugMacInfo;
+ else if (const_sect_name == g_sect_name_dwarf_debug_names)
+ section_type = eSectionTypeDWARFDebugNames;
+ else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)
+ section_type = eSectionTypeDWARFDebugPubNames;
+ else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)
+ section_type = eSectionTypeDWARFDebugPubTypes;
+ else if (const_sect_name == g_sect_name_dwarf_debug_ranges)
+ section_type = eSectionTypeDWARFDebugRanges;
+ else if (const_sect_name == g_sect_name_dwarf_debug_str)
+ section_type = eSectionTypeDWARFDebugStr;
+ else if (const_sect_name == g_sect_name_dwarf_debug_types)
+ section_type = eSectionTypeDWARFDebugTypes;
+ else if (const_sect_name == g_sect_name_eh_frame)
+ section_type = eSectionTypeEHFrame;
+ else if (const_sect_name == g_sect_name_go_symtab)
+ section_type = eSectionTypeGoSymtab;
+ else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) {
+ section_type = eSectionTypeCode;
+ } else if (m_sect_headers[idx].flags &
+ llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) {
+ section_type = eSectionTypeData;
+ } else if (m_sect_headers[idx].flags &
+ llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
+ if (m_sect_headers[idx].size == 0)
+ section_type = eSectionTypeZeroFill;
+ else
section_type = eSectionTypeData;
- } else if (m_sect_headers[idx].flags &
- llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
- if (m_sect_headers[idx].size == 0)
- section_type = eSectionTypeZeroFill;
- else
- section_type = eSectionTypeData;
- }
-
- // Use a segment ID of the segment index shifted left by 8 so they
- // never conflict with any of the sections.
- SectionSP section_sp(new Section(
- module_sp, // Module to which this section belongs
- this, // Object file to which this section belongs
- idx + 1, // Section ID is the 1 based segment index shifted right by
- // 8 bits as not to collide with any of the 256 section IDs
- // that are possible
- const_sect_name, // Name of this section
- section_type, // This section is a container of other sections.
- m_coff_header_opt.image_base +
- m_sect_headers[idx].vmaddr, // File VM address == addresses as
- // they are found in the object file
- m_sect_headers[idx].vmsize, // VM size in bytes of this section
- m_sect_headers[idx]
- .offset, // Offset to the data for this section in the file
- m_sect_headers[idx]
- .size, // Size in bytes of this section as found in the file
- m_coff_header_opt.sect_alignment, // Section alignment
- m_sect_headers[idx].flags)); // Flags for this section
-
- // section_sp->SetIsEncrypted (segment_is_encrypted);
-
- unified_section_list.AddSection(section_sp);
- m_sections_ap->AddSection(section_sp);
}
+
+ // Use a segment ID of the segment index shifted left by 8 so they
+ // never conflict with any of the sections.
+ SectionSP section_sp(new Section(
+ module_sp, // Module to which this section belongs
+ this, // Object file to which this section belongs
+ idx + 1, // Section ID is the 1 based segment index shifted right by
+ // 8 bits as not to collide with any of the 256 section IDs
+ // that are possible
+ const_sect_name, // Name of this section
+ section_type, // This section is a container of other sections.
+ m_coff_header_opt.image_base +
+ m_sect_headers[idx].vmaddr, // File VM address == addresses as
+ // they are found in the object file
+ m_sect_headers[idx].vmsize, // VM size in bytes of this section
+ m_sect_headers[idx]
+ .offset, // Offset to the data for this section in the file
+ m_sect_headers[idx]
+ .size, // Size in bytes of this section as found in the file
+ m_coff_header_opt.sect_alignment, // Section alignment
+ m_sect_headers[idx].flags)); // Flags for this section
+
+ // section_sp->SetIsEncrypted (segment_is_encrypted);
+
+ unified_section_list.AddSection(section_sp);
+ m_sections_ap->AddSection(section_sp);
}
}
}
bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; }
+uint32_t ObjectFilePECOFF::ParseDependentModules() {
+ ModuleSP module_sp(GetModule());
+ if (!module_sp)
+ return 0;
+
+ std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+ if (m_deps_filespec)
+ return m_deps_filespec->GetSize();
+
+ // Cache coff binary if it is not done yet.
+ if (!CreateBinary())
+ return 0;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p ObjectFilePECOFF::ParseDependentModules() module = %p "
+ "(%s), binary = %p (Bin = %p)",
+ static_cast<void *>(this), static_cast<void *>(module_sp.get()),
+ module_sp->GetSpecificationDescription().c_str(),
+ static_cast<void *>(m_owningbin.getPointer()),
+ m_owningbin ? static_cast<void *>(m_owningbin->getBinary())
+ : nullptr);
+
+ auto COFFObj =
+ llvm::dyn_cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());
+ if (!COFFObj)
+ return 0;
+
+ m_deps_filespec = FileSpecList();
+
+ for (const auto &entry : COFFObj->import_directories()) {
+ llvm::StringRef dll_name;
+ auto ec = entry.getName(dll_name);
+ // Report a bogus entry.
+ if (ec != std::error_code()) {
+ if (log)
+ log->Printf("ObjectFilePECOFF::ParseDependentModules() - failed to get "
+ "import directory entry name: %s",
+ ec.message().c_str());
+ continue;
+ }
+
+ // At this moment we only have the base name of the DLL. The full path can
+ // only be seen after the dynamic loading. Our best guess is Try to get it
+ // with the help of the object file's directory.
+ llvm::SmallString<128> dll_fullpath;
+ FileSpec dll_specs(dll_name);
+ dll_specs.GetDirectory().SetString(m_file.GetDirectory().GetCString());
+
+ if (!llvm::sys::fs::real_path(dll_specs.GetPath(), dll_fullpath))
+ m_deps_filespec->Append(FileSpec(dll_fullpath));
+ else {
+ // Known DLLs or DLL not found in the object file directory.
+ m_deps_filespec->Append(FileSpec(dll_name));
+ }
+ }
+ return m_deps_filespec->GetSize();
+}
+
uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) {
- return 0;
+ auto num_modules = ParseDependentModules();
+ auto original_size = files.GetSize();
+
+ for (unsigned i = 0; i < num_modules; ++i)
+ files.AppendIfUnique(m_deps_filespec->GetFileSpecAtIndex(i));
+
+ return files.GetSize() - original_size;
}
lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
@@ -811,12 +917,12 @@ lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
return m_entry_point_address;
SectionList *section_list = GetSectionList();
- addr_t offset = m_coff_header_opt.entry;
+ addr_t file_addr = m_coff_header_opt.entry + m_coff_header_opt.image_base;
if (!section_list)
- m_entry_point_address.SetOffset(offset);
+ m_entry_point_address.SetOffset(file_addr);
else
- m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
+ m_entry_point_address.ResolveAddressUsingFileSections(file_addr, section_list);
return m_entry_point_address;
}
@@ -834,8 +940,7 @@ void ObjectFilePECOFF::Dump(Stream *s) {
s->Indent();
s->PutCString("ObjectFilePECOFF");
- ArchSpec header_arch;
- GetArchitecture(header_arch);
+ ArchSpec header_arch = GetArchitecture();
*s << ", file = '" << m_file
<< "', arch = " << header_arch.GetArchitectureName() << "\n";
@@ -857,6 +962,9 @@ void ObjectFilePECOFF::Dump(Stream *s) {
s->EOL();
DumpSectionHeaders(s);
s->EOL();
+
+ DumpDependentModules(s);
+ s->EOL();
}
}
@@ -974,8 +1082,7 @@ void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s,
//----------------------------------------------------------------------
void ObjectFilePECOFF::DumpSectionHeader(Stream *s,
const section_header_t &sh) {
- std::string name;
- GetSectionName(name, sh);
+ std::string name = GetSectionName(sh);
s->Printf("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x "
"0x%4.4x 0x%8.8x\n",
name.c_str(), sh.vmaddr, sh.vmsize, sh.offset, sh.size, sh.reloff,
@@ -1004,6 +1111,22 @@ void ObjectFilePECOFF::DumpSectionHeaders(Stream *s) {
}
}
+//----------------------------------------------------------------------
+// DumpDependentModules
+//
+// Dump all of the dependent modules to the specified output stream
+//----------------------------------------------------------------------
+void ObjectFilePECOFF::DumpDependentModules(lldb_private::Stream *s) {
+ auto num_modules = ParseDependentModules();
+ if (num_modules > 0) {
+ s->PutCString("Dependent Modules\n");
+ for (unsigned i = 0; i < num_modules; ++i) {
+ auto spec = m_deps_filespec->GetFileSpecAtIndex(i);
+ s->Printf(" %s\n", spec.GetFilename().GetCString());
+ }
+ }
+}
+
bool ObjectFilePECOFF::IsWindowsSubsystem() {
switch (m_coff_header_opt.subsystem) {
case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE:
@@ -1019,9 +1142,11 @@ bool ObjectFilePECOFF::IsWindowsSubsystem() {
}
}
-bool ObjectFilePECOFF::GetArchitecture(ArchSpec &arch) {
+ArchSpec ObjectFilePECOFF::GetArchitecture() {
uint16_t machine = m_coff_header.machine;
switch (machine) {
+ default:
+ break;
case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
case llvm::COFF::IMAGE_FILE_MACHINE_I386:
case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
@@ -1029,14 +1154,13 @@ bool ObjectFilePECOFF::GetArchitecture(ArchSpec &arch) {
case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
+ ArchSpec arch;
arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE,
IsWindowsSubsystem() ? llvm::Triple::Win32
: llvm::Triple::UnknownOS);
- return true;
- default:
- break;
+ return arch;
}
- return false;
+ return ArchSpec();
}
ObjectFile::Type ObjectFilePECOFF::CalculateType() {
@@ -1050,6 +1174,7 @@ ObjectFile::Type ObjectFilePECOFF::CalculateType() {
}
ObjectFile::Strata ObjectFilePECOFF::CalculateStrata() { return eStrataUser; }
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
index d8a94e19d34f..9fd313f26a0a 100644
--- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -10,13 +10,10 @@
#ifndef liblldb_ObjectFilePECOFF_h_
#define liblldb_ObjectFilePECOFF_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/ObjectFile.h"
+#include "llvm/Object/Binary.h"
class ObjectFilePECOFF : public lldb_private::ObjectFile {
public:
@@ -113,7 +110,7 @@ public:
void Dump(lldb_private::Stream *s) override;
- bool GetArchitecture(lldb_private::ArchSpec &arch) override;
+ lldb_private::ArchSpec GetArchitecture() override;
bool GetUUID(lldb_private::UUID *uuid) override;
@@ -261,6 +258,8 @@ protected:
bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr);
bool ParseSectionHeaders(uint32_t offset);
+ uint32_t ParseDependentModules();
+
static void DumpDOSHeader(lldb_private::Stream *s,
const dos_header_t &header);
static void DumpCOFFHeader(lldb_private::Stream *s,
@@ -269,19 +268,27 @@ protected:
const coff_opt_header_t &header);
void DumpSectionHeaders(lldb_private::Stream *s);
void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh);
- bool GetSectionName(std::string &sect_name, const section_header_t &sect);
+ void DumpDependentModules(lldb_private::Stream *s);
+
+ llvm::StringRef GetSectionName(const section_header_t &sect);
typedef std::vector<section_header_t> SectionHeaderColl;
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
private:
+ bool CreateBinary();
+
+private:
dos_header_t m_dos_header;
coff_header_t m_coff_header;
coff_opt_header_t m_coff_header_opt;
SectionHeaderColl m_sect_headers;
lldb::addr_t m_image_base;
lldb_private::Address m_entry_point_address;
+ llvm::Optional<lldb_private::FileSpecList> m_deps_filespec;
+ typedef llvm::object::OwningBinary<llvm::object::Binary> OWNBINType;
+ llvm::Optional<OWNBINType> m_owningbin;
};
#endif // liblldb_ObjectFilePECOFF_h_
diff --git a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
index d6553f6e5142..e77888c871b5 100644
--- a/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
+++ b/source/Plugins/ObjectFile/PECOFF/WindowsMiniDump.cpp
@@ -16,7 +16,7 @@
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
-#include <dbghelp.h> // for MiniDumpWriteDump
+#include <dbghelp.h>
#endif
namespace lldb_private {
diff --git a/source/Plugins/OperatingSystem/CMakeLists.txt b/source/Plugins/OperatingSystem/CMakeLists.txt
index 1f017adcd02b..655007a0aab9 100644
--- a/source/Plugins/OperatingSystem/CMakeLists.txt
+++ b/source/Plugins/OperatingSystem/CMakeLists.txt
@@ -1,2 +1 @@
-add_subdirectory(Go)
add_subdirectory(Python)
diff --git a/source/Plugins/OperatingSystem/Go/CMakeLists.txt b/source/Plugins/OperatingSystem/Go/CMakeLists.txt
deleted file mode 100644
index 27e952a84dfc..000000000000
--- a/source/Plugins/OperatingSystem/Go/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginOSGo PLUGIN
- OperatingSystemGo.cpp
-
- LINK_LIBS
- lldbCore
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
deleted file mode 100644
index 3f6083931513..000000000000
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ /dev/null
@@ -1,498 +0,0 @@
-//===-- OperatingSystemGo.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
-#include <unordered_map>
-
-// Other libraries and framework includes
-// Project includes
-#include "OperatingSystemGo.h"
-
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
-#include "Plugins/Process/Utility/RegisterContextMemory.h"
-#include "Plugins/Process/Utility/ThreadMemory.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Core/ValueObjectVariable.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/OptionGroupBoolean.h"
-#include "lldb/Interpreter/OptionGroupUInt64.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/Property.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/VariableList.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadList.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/StreamString.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-static PropertyDefinition g_properties[] = {
- {"enable", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
- "Specify whether goroutines should be treated as threads."},
- {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
-
-enum {
- ePropertyEnableGoroutines,
-};
-
-class PluginProperties : public Properties {
-public:
- PluginProperties() : Properties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- ~PluginProperties() override = default;
-
- static ConstString GetSettingName() {
- return OperatingSystemGo::GetPluginNameStatic();
- }
-
- bool GetEnableGoroutines() {
- const uint32_t idx = ePropertyEnableGoroutines;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(
- NULL, idx, g_properties[idx].default_uint_value);
- }
-
- bool SetEnableGoroutines(bool enable) {
- const uint32_t idx = ePropertyEnableGoroutines;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, enable);
- }
-};
-
-typedef std::shared_ptr<PluginProperties> OperatingSystemGoPropertiesSP;
-
-static const OperatingSystemGoPropertiesSP &GetGlobalPluginProperties() {
- static OperatingSystemGoPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset(new PluginProperties());
- return g_settings_sp;
-}
-
-class RegisterContextGo : public RegisterContextMemory {
-public:
- RegisterContextGo(lldb_private::Thread &thread, uint32_t concrete_frame_idx,
- DynamicRegisterInfo &reg_info, lldb::addr_t reg_data_addr)
- : RegisterContextMemory(thread, concrete_frame_idx, reg_info,
- reg_data_addr) {
- const RegisterInfo *sp = reg_info.GetRegisterInfoAtIndex(
- reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_SP));
- const RegisterInfo *pc = reg_info.GetRegisterInfoAtIndex(
- reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
- LLDB_REGNUM_GENERIC_PC));
- size_t byte_size = std::max(sp->byte_offset + sp->byte_size,
- pc->byte_offset + pc->byte_size);
-
- DataBufferSP reg_data_sp(new DataBufferHeap(byte_size, 0));
- m_reg_data.SetData(reg_data_sp);
- }
-
- ~RegisterContextGo() override = default;
-
- bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &reg_value) override {
- switch (reg_info->kinds[eRegisterKindGeneric]) {
- case LLDB_REGNUM_GENERIC_SP:
- case LLDB_REGNUM_GENERIC_PC:
- return RegisterContextMemory::ReadRegister(reg_info, reg_value);
- default:
- reg_value.SetValueToInvalid();
- return true;
- }
- }
-
- bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &reg_value) override {
- switch (reg_info->kinds[eRegisterKindGeneric]) {
- case LLDB_REGNUM_GENERIC_SP:
- case LLDB_REGNUM_GENERIC_PC:
- return RegisterContextMemory::WriteRegister(reg_info, reg_value);
- default:
- return false;
- }
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN(RegisterContextGo);
-};
-
-} // anonymous namespace
-
-struct OperatingSystemGo::Goroutine {
- uint64_t m_lostack;
- uint64_t m_histack;
- uint64_t m_goid;
- addr_t m_gobuf;
- uint32_t m_status;
-};
-
-void OperatingSystemGo::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
-}
-
-void OperatingSystemGo::DebuggerInitialize(Debugger &debugger) {
- if (!PluginManager::GetSettingForOperatingSystemPlugin(
- debugger, PluginProperties::GetSettingName())) {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForOperatingSystemPlugin(
- debugger, GetGlobalPluginProperties()->GetValueProperties(),
- ConstString("Properties for the goroutine thread plug-in."),
- is_global_setting);
- }
-}
-
-void OperatingSystemGo::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
-}
-
-OperatingSystem *OperatingSystemGo::CreateInstance(Process *process,
- bool force) {
- if (!force) {
- TargetSP target_sp = process->CalculateTarget();
- if (!target_sp)
- return nullptr;
- ModuleList &module_list = target_sp->GetImages();
- std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
- const size_t num_modules = module_list.GetSize();
- bool found_go_runtime = false;
- for (size_t i = 0; i < num_modules; ++i) {
- Module *module = module_list.GetModulePointerAtIndexUnlocked(i);
- const SectionList *section_list = module->GetSectionList();
- if (section_list) {
- SectionSP section_sp(
- section_list->FindSectionByType(eSectionTypeGoSymtab, true));
- if (section_sp) {
- found_go_runtime = true;
- break;
- }
- }
- }
- if (!found_go_runtime)
- return nullptr;
- }
- return new OperatingSystemGo(process);
-}
-
-OperatingSystemGo::OperatingSystemGo(lldb_private::Process *process)
- : OperatingSystem(process), m_reginfo(new DynamicRegisterInfo) {}
-
-OperatingSystemGo::~OperatingSystemGo() = default;
-
-ConstString OperatingSystemGo::GetPluginNameStatic() {
- static ConstString g_name("goroutines");
- return g_name;
-}
-
-const char *OperatingSystemGo::GetPluginDescriptionStatic() {
- return "Operating system plug-in that reads runtime data-structures for "
- "goroutines.";
-}
-
-bool OperatingSystemGo::Init(ThreadList &threads) {
- if (threads.GetSize(false) < 1)
- return false;
- TargetSP target_sp = m_process->CalculateTarget();
- if (!target_sp)
- return false;
- // Go 1.6 stores goroutines in a slice called runtime.allgs
- ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs");
- if (allgs_sp) {
- m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true);
- m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true);
- } else {
- // Go 1.4 stores goroutines in the variable runtime.allg.
- m_allg_sp = FindGlobal(target_sp, "runtime.allg");
- m_allglen_sp = FindGlobal(target_sp, "runtime.allglen");
- }
-
- if (m_allg_sp && !m_allglen_sp) {
- StreamSP error_sp = target_sp->GetDebugger().GetAsyncErrorStream();
- error_sp->Printf("Unsupported Go runtime version detected.");
- return false;
- }
-
- if (!m_allg_sp)
- return false;
-
- RegisterContextSP real_registers_sp =
- threads.GetThreadAtIndex(0, false)->GetRegisterContext();
-
- std::unordered_map<size_t, ConstString> register_sets;
- for (size_t set_idx = 0; set_idx < real_registers_sp->GetRegisterSetCount();
- ++set_idx) {
- const RegisterSet *set = real_registers_sp->GetRegisterSet(set_idx);
- ConstString name(set->name);
- for (size_t reg_idx = 0; reg_idx < set->num_registers; ++reg_idx) {
- register_sets[reg_idx] = name;
- }
- }
- TypeSP gobuf_sp = FindType(target_sp, "runtime.gobuf");
- if (!gobuf_sp) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
-
- if (log)
- log->Printf("OperatingSystemGo unable to find struct Gobuf");
- return false;
- }
- CompilerType gobuf_type(gobuf_sp->GetLayoutCompilerType());
- for (size_t idx = 0; idx < real_registers_sp->GetRegisterCount(); ++idx) {
- RegisterInfo reg = *real_registers_sp->GetRegisterInfoAtIndex(idx);
- int field_index = -1;
- if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) {
- field_index = 0;
- } else if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC) {
- field_index = 1;
- }
- if (field_index == -1) {
- reg.byte_offset = ~0;
- } else {
- std::string field_name;
- uint64_t bit_offset = 0;
- CompilerType field_type = gobuf_type.GetFieldAtIndex(
- field_index, field_name, &bit_offset, nullptr, nullptr);
- reg.byte_size = field_type.GetByteSize(nullptr);
- reg.byte_offset = bit_offset / 8;
- }
- ConstString name(reg.name);
- ConstString alt_name(reg.alt_name);
- m_reginfo->AddRegister(reg, name, alt_name, register_sets[idx]);
- }
- return true;
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-ConstString OperatingSystemGo::GetPluginName() { return GetPluginNameStatic(); }
-
-uint32_t OperatingSystemGo::GetPluginVersion() { return 1; }
-
-bool OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &real_thread_list,
- ThreadList &new_thread_list) {
- new_thread_list = real_thread_list;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
-
- if (!(m_allg_sp || Init(real_thread_list)) || (m_allg_sp && !m_allglen_sp) ||
- !GetGlobalPluginProperties()->GetEnableGoroutines()) {
- return new_thread_list.GetSize(false) > 0;
- }
-
- if (log)
- log->Printf("OperatingSystemGo::UpdateThreadList(%d, %d, %d) fetching "
- "thread data from Go for pid %" PRIu64,
- old_thread_list.GetSize(false), real_thread_list.GetSize(false),
- new_thread_list.GetSize(0), m_process->GetID());
- uint64_t allglen = m_allglen_sp->GetValueAsUnsigned(0);
- if (allglen == 0) {
- return new_thread_list.GetSize(false) > 0;
- }
- std::vector<Goroutine> goroutines;
- // The threads that are in "new_thread_list" upon entry are the threads from
- // the lldb_private::Process subclass, no memory threads will be in this
- // list.
-
- Status err;
- for (uint64_t i = 0; i < allglen; ++i) {
- goroutines.push_back(CreateGoroutineAtIndex(i, err));
- if (err.Fail()) {
- LLDB_LOG(log, "error: {0}", err);
- return new_thread_list.GetSize(false) > 0;
- }
- }
- // Make a map so we can match goroutines with backing threads.
- std::map<uint64_t, ThreadSP> stack_map;
- for (uint32_t i = 0; i < real_thread_list.GetSize(false); ++i) {
- ThreadSP thread = real_thread_list.GetThreadAtIndex(i, false);
- stack_map[thread->GetRegisterContext()->GetSP()] = thread;
- }
- for (const Goroutine &goroutine : goroutines) {
- if (0 /* Gidle */ == goroutine.m_status ||
- 6 /* Gdead */ == goroutine.m_status) {
- continue;
- }
- ThreadSP memory_thread =
- old_thread_list.FindThreadByID(goroutine.m_goid, false);
- if (memory_thread && IsOperatingSystemPluginThread(memory_thread) &&
- memory_thread->IsValid()) {
- memory_thread->ClearBackingThread();
- } else {
- memory_thread.reset(new ThreadMemory(*m_process, goroutine.m_goid, "", "",
- goroutine.m_gobuf));
- }
- // Search for the backing thread if the goroutine is running.
- if (2 == (goroutine.m_status & 0xfff)) {
- auto backing_it = stack_map.lower_bound(goroutine.m_lostack);
- if (backing_it != stack_map.end()) {
- if (goroutine.m_histack >= backing_it->first) {
- if (log)
- log->Printf(
- "OperatingSystemGo::UpdateThreadList found backing thread "
- "%" PRIx64 " (%" PRIx64 ") for thread %" PRIx64 "",
- backing_it->second->GetID(),
- backing_it->second->GetProtocolID(), memory_thread->GetID());
- memory_thread->SetBackingThread(backing_it->second);
- new_thread_list.RemoveThreadByID(backing_it->second->GetID(), false);
- }
- }
- }
- new_thread_list.AddThread(memory_thread);
- }
-
- return new_thread_list.GetSize(false) > 0;
-}
-
-void OperatingSystemGo::ThreadWasSelected(Thread *thread) {}
-
-RegisterContextSP
-OperatingSystemGo::CreateRegisterContextForThread(Thread *thread,
- addr_t reg_data_addr) {
- RegisterContextSP reg_ctx_sp;
- if (!thread)
- return reg_ctx_sp;
-
- if (!IsOperatingSystemPluginThread(thread->shared_from_this()))
- return reg_ctx_sp;
-
- reg_ctx_sp.reset(
- new RegisterContextGo(*thread, 0, *m_reginfo, reg_data_addr));
- return reg_ctx_sp;
-}
-
-StopInfoSP
-OperatingSystemGo::CreateThreadStopReason(lldb_private::Thread *thread) {
- StopInfoSP stop_info_sp;
- return stop_info_sp;
-}
-
-lldb::ThreadSP OperatingSystemGo::CreateThread(lldb::tid_t tid,
- addr_t context) {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
-
- if (log)
- log->Printf("OperatingSystemGo::CreateThread (tid = 0x%" PRIx64
- ", context = 0x%" PRIx64 ") not implemented",
- tid, context);
-
- return ThreadSP();
-}
-
-ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) {
- VariableList variable_list;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
-
- if (log) {
- log->Printf(
- "exe: %s",
- target->GetExecutableModule()->GetSpecificationDescription().c_str());
- log->Printf("modules: %zu", target->GetImages().GetSize());
- }
-
- uint32_t match_count = target->GetImages().FindGlobalVariables(
- ConstString(name), 1, variable_list);
- if (match_count > 0) {
- ExecutionContextScope *exe_scope = target->GetProcessSP().get();
- if (exe_scope == NULL)
- exe_scope = target.get();
- return ValueObjectVariable::Create(exe_scope,
- variable_list.GetVariableAtIndex(0));
- }
- return ValueObjectSP();
-}
-
-TypeSP OperatingSystemGo::FindType(TargetSP target_sp, const char *name) {
- ConstString const_typename(name);
- SymbolContext sc;
- const bool exact_match = false;
-
- const ModuleList &module_list = target_sp->GetImages();
- size_t count = module_list.GetSize();
- for (size_t idx = 0; idx < count; idx++) {
- ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
- if (module_sp) {
- TypeSP type_sp(module_sp->FindFirstType(sc, const_typename, exact_match));
- if (type_sp)
- return type_sp;
- }
- }
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS));
-
- if (log)
- log->Printf("OperatingSystemGo::FindType(%s): not found", name);
- return TypeSP();
-}
-
-OperatingSystemGo::Goroutine
-OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Status &err) {
- err.Clear();
- Goroutine result = {};
- ValueObjectSP g =
- m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
- if (err.Fail()) {
- return result;
- }
-
- ConstString name("goid");
- ValueObjectSP val = g->GetChildMemberWithName(name, true);
- bool success = false;
- result.m_goid = val->GetValueAsUnsigned(0, &success);
- if (!success) {
- err.SetErrorToGenericError();
- err.SetErrorString("unable to read goid");
- return result;
- }
- name.SetCString("atomicstatus");
- val = g->GetChildMemberWithName(name, true);
- result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success);
- if (!success) {
- err.SetErrorToGenericError();
- err.SetErrorString("unable to read atomicstatus");
- return result;
- }
- name.SetCString("sched");
- val = g->GetChildMemberWithName(name, true);
- result.m_gobuf = val->GetAddressOf(false);
- name.SetCString("stack");
- val = g->GetChildMemberWithName(name, true);
- name.SetCString("lo");
- ValueObjectSP child = val->GetChildMemberWithName(name, true);
- result.m_lostack = child->GetValueAsUnsigned(0, &success);
- if (!success) {
- err.SetErrorToGenericError();
- err.SetErrorString("unable to read stack.lo");
- return result;
- }
- name.SetCString("hi");
- child = val->GetChildMemberWithName(name, true);
- result.m_histack = child->GetValueAsUnsigned(0, &success);
- if (!success) {
- err.SetErrorToGenericError();
- err.SetErrorString("unable to read stack.hi");
- return result;
- }
- return result;
-}
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h
deleted file mode 100644
index 5d255a348a63..000000000000
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h
+++ /dev/null
@@ -1,90 +0,0 @@
-//===-- OperatingSystemGo.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_OperatingSystemGo_h_
-#define _liblldb_OperatingSystemGo_h_
-
-// C Includes
-// C++ Includes
-#include <memory>
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Target/OperatingSystem.h"
-
-class DynamicRegisterInfo;
-
-class OperatingSystemGo : public lldb_private::OperatingSystem {
-public:
- OperatingSystemGo(lldb_private::Process *process);
-
- ~OperatingSystemGo() override;
-
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static lldb_private::OperatingSystem *
- CreateInstance(lldb_private::Process *process, bool force);
-
- static void Initialize();
-
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // lldb_private::PluginInterface Methods
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // lldb_private::OperatingSystem Methods
- //------------------------------------------------------------------
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &real_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- void ThreadWasSelected(lldb_private::Thread *thread) override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForThread(lldb_private::Thread *thread,
- lldb::addr_t reg_data_addr) override;
-
- lldb::StopInfoSP
- CreateThreadStopReason(lldb_private::Thread *thread) override;
-
- //------------------------------------------------------------------
- // Method for lazy creation of threads on demand
- //------------------------------------------------------------------
- lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) override;
-
-private:
- struct Goroutine;
-
- static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target,
- const char *name);
-
- static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name);
-
- bool Init(lldb_private::ThreadList &threads);
-
- Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Status &err);
-
- std::unique_ptr<DynamicRegisterInfo> m_reginfo;
- lldb::ValueObjectSP m_allg_sp;
- lldb::ValueObjectSP m_allglen_sp;
-};
-
-#endif // liblldb_OperatingSystemGo_h_
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
index d6252c473270..89a0f2253936 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -10,9 +10,6 @@
#ifndef LLDB_DISABLE_PYTHON
#include "OperatingSystemPython.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
#include "Plugins/Process/Utility/RegisterContextDummy.h"
#include "Plugins/Process/Utility/RegisterContextMemory.h"
@@ -20,7 +17,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
@@ -32,6 +28,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StructuredData.h"
@@ -53,7 +50,8 @@ OperatingSystem *OperatingSystemPython::CreateInstance(Process *process,
// Python OperatingSystem plug-ins must be requested by name, so force must
// be true
FileSpec python_os_plugin_spec(process->GetPythonOSPluginPath());
- if (python_os_plugin_spec && python_os_plugin_spec.Exists()) {
+ if (python_os_plugin_spec &&
+ FileSystem::Instance().Exists(python_os_plugin_spec)) {
std::unique_ptr<OperatingSystemPython> os_ap(
new OperatingSystemPython(process, python_os_plugin_spec));
if (os_ap.get() && os_ap->IsValid())
@@ -215,7 +213,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list,
// beginning of the list
uint32_t insert_idx = 0;
for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) {
- if (core_used_map[core_idx] == false) {
+ if (!core_used_map[core_idx]) {
new_thread_list.InsertThread(
core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx);
++insert_idx;
diff --git a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
index 2e1680410962..c812464fa747 100644
--- a/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ b/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -12,10 +12,6 @@
#ifndef LLDB_DISABLE_PYTHON
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Platform/Android/AdbClient.cpp b/source/Plugins/Platform/Android/AdbClient.cpp
index 4cd8c645dd76..0ad30a528954 100644
--- a/source/Plugins/Platform/Android/AdbClient.cpp
+++ b/source/Plugins/Platform/Android/AdbClient.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// Other libraries and framework includes
#include "AdbClient.h"
#include "llvm/ADT/STLExtras.h"
@@ -484,7 +483,7 @@ Status AdbClient::SyncService::internalPushFile(const FileSpec &local_file,
return Status("Failed to send file chunk: %s", error.AsCString());
}
error = SendSyncRequest(
- kDONE, llvm::sys::toTimeT(FileSystem::GetModificationTime(local_file)),
+ kDONE, llvm::sys::toTimeT(FileSystem::Instance().GetModificationTime(local_file)),
nullptr);
if (error.Fail())
return error;
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index 4477fe371d34..a56ab0e30153 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -9,15 +9,14 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/UriParser.h"
-// Project includes
#include "AdbClient.h"
#include "PlatformAndroid.h"
#include "PlatformAndroidRemoteGDBServer.h"
@@ -75,7 +74,7 @@ PlatformSP PlatformAndroid::CreateInstance(bool force, const ArchSpec *arch) {
}
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getVendor()) {
case llvm::Triple::PC:
@@ -193,7 +192,7 @@ Status PlatformAndroid::GetFile(const FileSpec &source,
if (IsHost() || !m_remote_platform_sp)
return PlatformLinux::GetFile(source, destination);
- FileSpec source_spec(source.GetPath(false), false, FileSpec::Style::posix);
+ FileSpec source_spec(source.GetPath(false), FileSpec::Style::posix);
if (source_spec.IsRelative())
source_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
source_spec.GetCString(false));
@@ -237,8 +236,7 @@ Status PlatformAndroid::PutFile(const FileSpec &source,
if (IsHost() || !m_remote_platform_sp)
return PlatformLinux::PutFile(source, destination, uid, gid);
- FileSpec destination_spec(destination.GetPath(false), false,
- FileSpec::Style::posix);
+ FileSpec destination_spec(destination.GetPath(false), FileSpec::Style::posix);
if (destination_spec.IsRelative())
destination_spec = GetRemoteWorkingDirectory().CopyByAppendingPathComponent(
destination_spec.GetCString(false));
@@ -343,7 +341,7 @@ Status PlatformAndroid::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
log->Printf("Failed to remove temp directory: %s", error.AsCString());
});
- FileSpec symfile_platform_filespec(tmpdir, false);
+ FileSpec symfile_platform_filespec(tmpdir);
symfile_platform_filespec.AppendPathComponent("symbolized.oat");
// Execute oatdump on the remote device to generate a file with symtab
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
index 4c12eb8c016d..2e7706cc246e 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -10,13 +10,9 @@
#ifndef liblldb_PlatformAndroid_h_
#define liblldb_PlatformAndroid_h_
-// C Includes
-// C++ Includes
#include <memory>
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Platform/Linux/PlatformLinux.h"
#include "AdbClient.h"
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 2415da31daf0..bbb03369d63c 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// Other libraries and framework includes
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Utility/Log.h"
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
index 1bd13ffe89fe..40356293b589 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h
@@ -10,13 +10,9 @@
#ifndef liblldb_PlatformAndroidRemoteGDBServer_h_
#define liblldb_PlatformAndroidRemoteGDBServer_h_
-// C Includes
-// C++ Includes
#include <map>
#include <utility>
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "llvm/ADT/Optional.h"
diff --git a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index bc8111d1078b..59cce3a6bc2b 100644
--- a/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -10,25 +10,21 @@
#include "PlatformFreeBSD.h"
#include "lldb/Host/Config.h"
-// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -52,7 +48,7 @@ PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) {
arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getOS()) {
case llvm::Triple::FreeBSD:
@@ -274,9 +270,9 @@ lldb::ProcessSP PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info,
TargetSP new_target_sp;
ArchSpec emptyArchSpec;
- error = debugger.GetTargetList().CreateTarget(debugger, "", emptyArchSpec,
- false, m_remote_platform_sp,
- new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", emptyArchSpec, eLoadDependentsNo, m_remote_platform_sp,
+ new_target_sp);
target = new_target_sp.get();
} else
error.Clear();
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
index 00327e485bf3..cc902b7f7ad5 100644
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
+++ b/source/Plugins/Platform/Kalimba/PlatformKalimba.cpp
@@ -11,9 +11,6 @@
#include "PlatformKalimba.h"
#include "lldb/Host/Config.h"
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -33,7 +30,7 @@ static uint32_t g_initialize_count = 0;
PlatformSP PlatformKalimba::CreateInstance(bool force, const ArchSpec *arch) {
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getVendor()) {
case llvm::Triple::CSR:
diff --git a/source/Plugins/Platform/Kalimba/PlatformKalimba.h b/source/Plugins/Platform/Kalimba/PlatformKalimba.h
index 53a8e5594aaa..efa78457d585 100644
--- a/source/Plugins/Platform/Kalimba/PlatformKalimba.h
+++ b/source/Plugins/Platform/Kalimba/PlatformKalimba.h
@@ -10,10 +10,6 @@
#ifndef liblldb_PlatformKalimba_h_
#define liblldb_PlatformKalimba_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Platform.h"
namespace lldb_private {
diff --git a/source/Plugins/Platform/Linux/PlatformLinux.cpp b/source/Plugins/Platform/Linux/PlatformLinux.cpp
index dbde91d7ab2d..7498c648d6e4 100644
--- a/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -10,23 +10,19 @@
#include "PlatformLinux.h"
#include "lldb/Host/Config.h"
-// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -50,7 +46,7 @@ PlatformSP PlatformLinux::CreateInstance(bool force, const ArchSpec *arch) {
arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getOS()) {
case llvm::Triple::Linux:
@@ -302,8 +298,8 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
if (target == nullptr) {
LLDB_LOG(log, "creating new target");
TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- nullptr, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
if (error.Fail()) {
LLDB_LOG(log, "failed to create new target: {0}", error);
return process_sp;
@@ -322,8 +318,8 @@ PlatformLinux::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Now create the gdb-remote process.
LLDB_LOG(log, "having target create process with gdb-remote plugin");
- process_sp = target->CreateProcess(
- launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
+ process_sp =
+ target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
if (!process_sp) {
error.SetErrorString("CreateProcess() failed for gdb-remote process");
diff --git a/source/Plugins/Platform/MacOSX/CMakeLists.txt b/source/Plugins/Platform/MacOSX/CMakeLists.txt
index f9663559069a..6f0d952c35fb 100644
--- a/source/Plugins/Platform/MacOSX/CMakeLists.txt
+++ b/source/Plugins/Platform/MacOSX/CMakeLists.txt
@@ -6,6 +6,7 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
PlatformRemoteAppleTV.cpp
PlatformRemoteAppleWatch.cpp
PlatformRemoteDarwinDevice.cpp
+ PlatformRemoteAppleBridge.cpp
)
list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
index 6852097117a1..a2f74a5fc8bc 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
@@ -9,16 +9,12 @@
#include "PlatformAppleSimulator.h"
-// C Includes
#if defined(__APPLE__)
#include <dlfcn.h>
#endif
-// C++ Includes
#include <mutex>
#include <thread>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -229,9 +225,8 @@ FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() {
cs_path.Printf(
"%s/Library/PrivateFrameworks/CoreSimulator.framework/CoreSimulator",
developer_dir);
- const bool resolve_path = true;
- m_core_simulator_framework_path =
- FileSpec(cs_path.GetData(), resolve_path);
+ m_core_simulator_framework_path = FileSpec(cs_path.GetData());
+ FileSystem::Instance().Resolve(*m_core_simulator_framework_path);
}
}
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
index 2536854e9630..daae376cc00b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h
@@ -10,12 +10,8 @@
#ifndef liblldb_PlatformAppleSimulator_h_
#define liblldb_PlatformAppleSimulator_h_
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Platform/MacOSX/PlatformDarwin.h"
#include "Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h"
#include "lldb/Utility/FileSpec.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
index e55cc0f4f6a4..62bd3c3ed1f8 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.cpp
@@ -9,10 +9,6 @@
#include "PlatformAppleTVSimulator.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -80,7 +76,7 @@ PlatformSP PlatformAppleTVSimulator::CreateInstance(bool force,
}
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
switch (arch->GetMachine()) {
case llvm::Triple::x86_64: {
const llvm::Triple &triple = arch->GetTriple();
@@ -93,7 +89,7 @@ PlatformSP PlatformAppleTVSimulator::CreateInstance(bool force,
// Only accept "unknown" for the vendor if the host is Apple and it
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
#endif
@@ -190,7 +186,7 @@ Status PlatformAppleTVSimulator::ResolveExecutable(
// ourselves
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
if (resolved_module_spec.GetArchitecture().IsValid()) {
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
NULL, NULL, NULL);
@@ -228,7 +224,7 @@ Status PlatformAppleTVSimulator::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -247,19 +243,20 @@ Status PlatformAppleTVSimulator::ResolveExecutable(
return error;
}
-static FileSpec::EnumerateDirectoryResult
+static FileSystem::EnumerateDirectoryResult
EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- const FileSpec &file_spec) {
+ llvm::StringRef path) {
if (ft == llvm::sys::fs::file_type::directory_file) {
+ FileSpec file_spec(path);
const char *filename = file_spec.GetFilename().GetCString();
if (filename &&
strncmp(filename, "AppleTVSimulator", strlen("AppleTVSimulator")) ==
0) {
::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSpec::eEnumerateDirectoryResultQuit;
+ return FileSystem::eEnumerateDirectoryResultQuit;
}
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() {
@@ -277,9 +274,9 @@ const char *PlatformAppleTVSimulator::GetSDKDirectoryAsCString() {
bool find_directories = true;
bool find_files = false;
bool find_other = false;
- FileSpec::EnumerateDirectory(sdks_directory, find_directories, find_files,
- find_other, EnumerateDirectoryCallback,
- sdk_dirname);
+ FileSystem::Instance().EnumerateDirectory(
+ sdks_directory, find_directories, find_files, find_other,
+ EnumerateDirectoryCallback, sdk_dirname);
if (sdk_dirname[0]) {
m_sdk_directory = sdks_directory;
@@ -315,13 +312,15 @@ Status PlatformAppleTVSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(platform_file_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
}
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
index 8cecb4d496ab..9a4da589c7ea 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleTVSimulator.h
@@ -10,10 +10,6 @@
#ifndef liblldb_PlatformAppleTVSimulator_h_
#define liblldb_PlatformAppleTVSimulator_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "PlatformDarwin.h"
class PlatformAppleTVSimulator : public PlatformDarwin {
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
index 8bbe0af0aec2..ec112cc0b9c5 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.cpp
@@ -9,10 +9,6 @@
#include "PlatformAppleWatchSimulator.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -79,7 +75,7 @@ PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force,
}
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
switch (arch->GetMachine()) {
case llvm::Triple::x86_64: {
const llvm::Triple &triple = arch->GetTriple();
@@ -92,7 +88,7 @@ PlatformSP PlatformAppleWatchSimulator::CreateInstance(bool force,
// Only accept "unknown" for the vendor if the host is Apple and it
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
#endif
@@ -190,7 +186,7 @@ Status PlatformAppleWatchSimulator::ResolveExecutable(
// ourselves
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
if (resolved_module_spec.GetArchitecture().IsValid()) {
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
NULL, NULL, NULL);
@@ -228,7 +224,7 @@ Status PlatformAppleWatchSimulator::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -247,19 +243,20 @@ Status PlatformAppleWatchSimulator::ResolveExecutable(
return error;
}
-static FileSpec::EnumerateDirectoryResult
+static FileSystem::EnumerateDirectoryResult
EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- const FileSpec &file_spec) {
+ llvm::StringRef path) {
if (ft == llvm::sys::fs::file_type::directory_file) {
+ FileSpec file_spec(path);
const char *filename = file_spec.GetFilename().GetCString();
if (filename &&
strncmp(filename, "AppleWatchSimulator",
strlen("AppleWatchSimulator")) == 0) {
::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSpec::eEnumerateDirectoryResultQuit;
+ return FileSystem::eEnumerateDirectoryResultQuit;
}
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() {
@@ -277,9 +274,9 @@ const char *PlatformAppleWatchSimulator::GetSDKDirectoryAsCString() {
bool find_directories = true;
bool find_files = false;
bool find_other = false;
- FileSpec::EnumerateDirectory(sdks_directory, find_directories, find_files,
- find_other, EnumerateDirectoryCallback,
- sdk_dirname);
+ FileSystem::Instance().EnumerateDirectory(
+ sdks_directory, find_directories, find_files, find_other,
+ EnumerateDirectoryCallback, sdk_dirname);
if (sdk_dirname[0]) {
m_sdk_directory = sdks_directory;
@@ -315,13 +312,15 @@ Status PlatformAppleWatchSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(platform_file_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
}
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
index 30aa42c964a5..c240a09e3afd 100644
--- a/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformAppleWatchSimulator.h
@@ -10,10 +10,6 @@
#ifndef liblldb_PlatformAppleWatchSimulator_h_
#define liblldb_PlatformAppleWatchSimulator_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "PlatformDarwin.h"
class PlatformAppleWatchSimulator : public PlatformDarwin {
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 886e3b6d9a05..3868d97700e0 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -9,14 +9,11 @@
#include "PlatformDarwin.h"
-// C Includes
#include <string.h>
-// C++ Includes
#include <algorithm>
#include <mutex>
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
@@ -33,7 +30,6 @@
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Timer.h"
@@ -43,7 +39,7 @@
#include "llvm/Support/VersionTuple.h"
#if defined(__APPLE__)
-#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
+#include <TargetConditionals.h>
#endif
using namespace lldb;
@@ -88,7 +84,7 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
ObjectFile *objfile = symfile->GetObjectFile();
if (objfile) {
FileSpec symfile_spec(objfile->GetFileSpec());
- if (symfile_spec && symfile_spec.Exists()) {
+ if (symfile_spec && FileSystem::Instance().Exists(symfile_spec)) {
while (module_spec.GetFilename()) {
std::string module_basename(
module_spec.GetFilename().GetCString());
@@ -130,20 +126,21 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
"%s/../Python/%s.py",
symfile_spec.GetDirectory().GetCString(),
original_module_basename.c_str());
- FileSpec script_fspec(path_string.GetString(), true);
- FileSpec orig_script_fspec(original_path_string.GetString(),
- true);
+ FileSpec script_fspec(path_string.GetString());
+ FileSystem::Instance().Resolve(script_fspec);
+ FileSpec orig_script_fspec(original_path_string.GetString());
+ FileSystem::Instance().Resolve(orig_script_fspec);
// if we did some replacements of reserved characters, and a
// file with the untampered name exists, then warn the user
// that the file as-is shall not be loaded
if (feedback_stream) {
if (module_basename != original_module_basename &&
- orig_script_fspec.Exists()) {
+ FileSystem::Instance().Exists(orig_script_fspec)) {
const char *reason_for_complaint =
was_keyword ? "conflicts with a keyword"
: "contains reserved characters";
- if (script_fspec.Exists())
+ if (FileSystem::Instance().Exists(script_fspec))
feedback_stream->Printf(
"warning: the symbol file '%s' contains a debug "
"script. However, its name"
@@ -167,7 +164,7 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
}
}
- if (script_fspec.Exists()) {
+ if (FileSystem::Instance().Exists(script_fspec)) {
file_list.Append(script_fspec);
break;
}
@@ -193,25 +190,12 @@ FileSpecList PlatformDarwin::LocateExecutableScriptingResources(
Status PlatformDarwin::ResolveSymbolFile(Target &target,
const ModuleSpec &sym_spec,
FileSpec &sym_file) {
- Status error;
sym_file = sym_spec.GetSymbolFileSpec();
-
- llvm::sys::fs::file_status st;
- if (status(sym_file.GetPath(), st, false)) {
- error.SetErrorString("Could not stat file!");
- return error;
- }
-
- if (exists(st)) {
- if (is_directory(st)) {
- sym_file = Symbols::FindSymbolFileInBundle(
- sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr());
- }
- } else {
- if (sym_spec.GetUUID().IsValid()) {
- }
+ if (FileSystem::Instance().IsDirectory(sym_file)) {
+ sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(),
+ sym_spec.GetArchitecturePtr());
}
- return error;
+ return {};
}
static lldb_private::Status
@@ -261,7 +245,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
if (!cache_path.empty()) {
std::string module_path(module_spec.GetFileSpec().GetPath());
cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path, false);
+ FileSpec module_cache_spec(cache_path);
// if rsync is supported, always bring in the file - rsync will be very
// efficient when files are the same on the local and remote end of the
@@ -270,7 +254,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
err = BringInRemoteFile(this, module_spec, module_cache_spec);
if (err.Fail())
return err;
- if (module_cache_spec.Exists()) {
+ if (FileSystem::Instance().Exists(module_cache_spec)) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
log->Printf("[%s] module %s/%s was rsynced and is now there",
@@ -286,7 +270,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
}
// try to find the module in the cache
- if (module_cache_spec.Exists()) {
+ if (FileSystem::Instance().Exists(module_cache_spec)) {
// get the local and remote MD5 and compare
if (m_remote_platform_sp) {
// when going over the *slow* GDB remote transfer mechanism we first
@@ -337,7 +321,7 @@ lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache(
Status err = BringInRemoteFile(this, module_spec, module_cache_spec);
if (err.Fail())
return err;
- if (module_cache_spec.Exists()) {
+ if (FileSystem::Instance().Exists(module_cache_spec)) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
log->Printf("[%s] module %s/%s is now cached and fine",
@@ -412,8 +396,8 @@ Status PlatformDarwin::GetSharedModule(
snprintf(new_path + search_path_len,
sizeof(new_path) - search_path_len, "/%s",
platform_path + bundle_directory_len);
- FileSpec new_file_spec(new_path, false);
- if (new_file_spec.Exists()) {
+ FileSpec new_file_spec(new_path);
+ if (FileSystem::Instance().Exists(new_file_spec)) {
ModuleSpec new_module_spec(module_spec);
new_module_spec.GetFileSpec() = new_file_spec;
Status new_error(Platform::GetSharedModule(
@@ -505,10 +489,7 @@ bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(
return false;
ObjectFile::Type obj_type = obj_file->GetType();
- if (obj_type == ObjectFile::eTypeDynamicLinker)
- return true;
- else
- return false;
+ return obj_type == ObjectFile::eTypeDynamicLinker;
}
bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx,
@@ -1167,9 +1148,9 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
if (xcode_select_prefix_dir)
xcode_dir_path.append(xcode_select_prefix_dir);
xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path");
- temp_file_spec.SetFile(xcode_dir_path, false, FileSpec::Style::native);
+ temp_file_spec.SetFile(xcode_dir_path, FileSpec::Style::native);
auto dir_buffer =
- DataBufferLLVM::CreateFromPath(temp_file_spec.GetPath());
+ FileSystem::Instance().CreateDataBuffer(temp_file_spec.GetPath());
if (dir_buffer && dir_buffer->GetByteSize() > 0) {
llvm::StringRef path_ref(dir_buffer->GetChars());
// Trim tailing newlines and make sure there is enough room for a null
@@ -1183,8 +1164,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
}
if (!developer_dir_path_valid) {
- FileSpec xcode_select_cmd("/usr/bin/xcode-select", false);
- if (xcode_select_cmd.Exists()) {
+ FileSpec xcode_select_cmd("/usr/bin/xcode-select");
+ if (FileSystem::Instance().Exists(xcode_select_cmd)) {
int exit_status = -1;
int signo = -1;
std::string command_output;
@@ -1206,8 +1187,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
}
developer_dir_path[i] = '\0';
- FileSpec devel_dir(developer_dir_path, false);
- if (llvm::sys::fs::is_directory(devel_dir.GetPath())) {
+ FileSpec devel_dir(developer_dir_path);
+ if (FileSystem::Instance().IsDirectory(devel_dir)) {
developer_dir_path_valid = true;
}
}
@@ -1215,9 +1196,8 @@ const char *PlatformDarwin::GetDeveloperDirectory() {
}
if (developer_dir_path_valid) {
- temp_file_spec.SetFile(developer_dir_path, false,
- FileSpec::Style::native);
- if (temp_file_spec.Exists()) {
+ temp_file_spec.SetFile(developer_dir_path, FileSpec::Style::native);
+ if (FileSystem::Instance().Exists(temp_file_spec)) {
m_developer_directory.assign(developer_dir_path);
return m_developer_directory.c_str();
}
@@ -1247,7 +1227,7 @@ BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {
FileSpecList bp_modules;
for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) {
const char *bp_module = g_bp_modules[i];
- bp_modules.Append(FileSpec(bp_module, false));
+ bp_modules.Append(FileSpec(bp_module));
}
bool internal = true;
@@ -1300,20 +1280,20 @@ static const char *const sdk_strings[] = {
};
static FileSpec CheckPathForXcode(const FileSpec &fspec) {
- if (fspec.Exists()) {
+ if (FileSystem::Instance().Exists(fspec)) {
const char substr[] = ".app/Contents";
std::string path_to_shlib = fspec.GetPath();
size_t pos = path_to_shlib.rfind(substr);
if (pos != std::string::npos) {
path_to_shlib.erase(pos + strlen(substr));
- FileSpec ret(path_to_shlib, false);
+ FileSpec ret(path_to_shlib);
FileSpec xcode_binary_path = ret;
xcode_binary_path.AppendPathComponent("MacOS");
xcode_binary_path.AppendPathComponent("Xcode");
- if (xcode_binary_path.Exists()) {
+ if (FileSystem::Instance().Exists(xcode_binary_path)) {
return ret;
}
}
@@ -1348,8 +1328,9 @@ static FileSpec GetXcodeContentsPath() {
if (!g_xcode_filespec) {
const char *developer_dir_env_var = getenv("DEVELOPER_DIR");
if (developer_dir_env_var && developer_dir_env_var[0]) {
- g_xcode_filespec =
- CheckPathForXcode(FileSpec(developer_dir_env_var, true));
+ FileSpec developer_dir_spec = FileSpec(developer_dir_env_var);
+ FileSystem::Instance().Resolve(developer_dir_spec);
+ g_xcode_filespec = CheckPathForXcode(developer_dir_spec);
}
// Fall back to using "xcrun" to find the selected Xcode
@@ -1373,7 +1354,7 @@ static FileSpec GetXcodeContentsPath() {
}
output.append("/..");
- g_xcode_filespec = CheckPathForXcode(FileSpec(output, false));
+ g_xcode_filespec = CheckPathForXcode(FileSpec(output));
}
}
}
@@ -1402,14 +1383,11 @@ bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
if (last_path_component) {
const llvm::StringRef sdk_name = last_path_component.GetStringRef();
- llvm::StringRef version_part;
-
- if (sdk_name.startswith(sdk_strings[(int)desired_type])) {
- version_part =
- sdk_name.drop_front(strlen(sdk_strings[(int)desired_type]));
- } else {
+ if (!sdk_name.startswith(sdk_strings[desired_type]))
return false;
- }
+ auto version_part =
+ sdk_name.drop_front(strlen(sdk_strings[desired_type]));
+ version_part.consume_back(".sdk");
llvm::VersionTuple version;
if (version.tryParse(version_part))
@@ -1420,23 +1398,24 @@ bool PlatformDarwin::SDKSupportsModules(SDKType desired_type,
return false;
}
-FileSpec::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(
- void *baton, llvm::sys::fs::file_type file_type, const FileSpec &spec) {
+FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(
+ void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {
SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);
+ FileSpec spec(path);
if (SDKSupportsModules(enumerator_info->sdk_type, spec)) {
enumerator_info->found_path = spec;
- return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
+ return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
}
- return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
+ return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
}
FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type,
const FileSpec &sdks_spec) {
// Look inside Xcode for the required installed iOS SDK version
- if (!llvm::sys::fs::is_directory(sdks_spec.GetPath())) {
+ if (!FileSystem::Instance().IsDirectory(sdks_spec)) {
return FileSpec();
}
@@ -1448,11 +1427,11 @@ FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type,
enumerator_info.sdk_type = sdk_type;
- FileSpec::EnumerateDirectory(sdks_spec.GetPath(), find_directories,
- find_files, find_other, DirectoryEnumerator,
- &enumerator_info);
+ FileSystem::Instance().EnumerateDirectory(
+ sdks_spec.GetPath(), find_directories, find_files, find_other,
+ DirectoryEnumerator, &enumerator_info);
- if (llvm::sys::fs::is_directory(enumerator_info.found_path.GetPath()))
+ if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))
return enumerator_info.found_path;
else
return FileSpec();
@@ -1499,7 +1478,7 @@ FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
version.getMinor().getValueOr(0));
native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());
- if (native_sdk_spec.Exists()) {
+ if (FileSystem::Instance().Exists(native_sdk_spec)) {
return native_sdk_spec;
}
}
@@ -1597,7 +1576,7 @@ void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
sysroot_spec = GetSDKDirectoryForModules(sdk_type);
}
- if (llvm::sys::fs::is_directory(sysroot_spec.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {
options.push_back("-isysroot");
options.push_back(sysroot_spec.GetPath());
}
@@ -1661,7 +1640,7 @@ lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
xcode_lldb_resources.AppendPathComponent("SharedFrameworks");
xcode_lldb_resources.AppendPathComponent("LLDB.framework");
xcode_lldb_resources.AppendPathComponent("Resources");
- if (xcode_lldb_resources.Exists()) {
+ if (FileSystem::Instance().Exists(xcode_lldb_resources)) {
FileSpec dir;
dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str());
g_executable_dirs.push_back(dir);
@@ -1675,7 +1654,7 @@ lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {
FileSpec executable_file;
executable_file.GetDirectory() = executable_dir.GetDirectory();
executable_file.GetFilename().SetCString(basename);
- if (executable_file.Exists())
+ if (FileSystem::Instance().Exists(executable_file))
return executable_file;
}
@@ -1759,7 +1738,7 @@ PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec
path_to_try.AppendPathComponent(path_parts[k]);
}
- if (path_to_try.Exists()) {
+ if (FileSystem::Instance().Exists(path_to_try)) {
ModuleSpec new_module_spec(module_spec);
new_module_spec.GetFileSpec() = path_to_try;
Status new_error(Platform::GetSharedModule(
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 3ad29ec1a0b9..f2dd9b1bc778 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -10,12 +10,9 @@
#ifndef liblldb_PlatformDarwin_h_
#define liblldb_PlatformDarwin_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FileSystem.h"
@@ -85,6 +82,12 @@ public:
static std::tuple<llvm::VersionTuple, llvm::StringRef>
ParseVersionBuildDir(llvm::StringRef str);
+ enum SDKType : unsigned {
+ MacOSX = 0,
+ iPhoneSimulator,
+ iPhoneOS,
+ };
+
protected:
void ReadLibdispatchOffsetsAddress(lldb_private::Process *process);
@@ -95,12 +98,6 @@ protected:
const lldb_private::FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
- enum class SDKType {
- MacOSX = 0,
- iPhoneSimulator,
- iPhoneOS,
- };
-
static bool SDKSupportsModules(SDKType sdk_type, llvm::VersionTuple version);
static bool SDKSupportsModules(SDKType desired_type,
@@ -111,9 +108,9 @@ protected:
SDKType sdk_type;
};
- static lldb_private::FileSpec::EnumerateDirectoryResult
+ static lldb_private::FileSystem::EnumerateDirectoryResult
DirectoryEnumerator(void *baton, llvm::sys::fs::file_type file_type,
- const lldb_private::FileSpec &spec);
+ llvm::StringRef path);
static lldb_private::FileSpec
FindSDKInXcodeForModules(SDKType sdk_type,
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
index 1e3216c0af5a..4c6d9459e225 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
@@ -13,10 +13,6 @@
#if defined(__APPLE__) // This Plugin uses the Mac-specific
// source/Host/macosx/cfcpp utilities
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -95,7 +91,7 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
// ArchSpec for normal userland debugging. It is only useful in kernel debug
// sessions and the DynamicLoaderDarwinPlugin (or a user doing 'platform
// select') will force the creation of this Platform plugin.
- if (force == false) {
+ if (!force) {
if (log)
log->Printf("PlatformDarwinKernel::%s() aborting creation of platform "
"because force == false",
@@ -106,7 +102,7 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
bool create = force;
LazyBool is_ios_debug_session = eLazyBoolCalculate;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getVendor()) {
case llvm::Triple::Apple:
@@ -115,7 +111,7 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
// Only accept "unknown" for vendor if the host is Apple and it "unknown"
// wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
default:
@@ -129,6 +125,7 @@ PlatformSP PlatformDarwinKernel::CreateInstance(bool force,
case llvm::Triple::IOS:
case llvm::Triple::WatchOS:
case llvm::Triple::TvOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
break;
// Only accept "vendor" for vendor if the host is Apple and it "unknown"
// wasn't specified (it was just returned because it was NOT specified)
@@ -186,14 +183,13 @@ const char *PlatformDarwinKernel::GetDescriptionStatic() {
/// Code to handle the PlatformDarwinKernel settings
//------------------------------------------------------------------
-static PropertyDefinition g_properties[] = {
+static constexpr PropertyDefinition g_properties[] = {
{"search-locally-for-kexts", OptionValue::eTypeBoolean, true, true, NULL,
- NULL, "Automatically search for kexts on the local system when doing "
+ {}, "Automatically search for kexts on the local system when doing "
"kernel debugging."},
- {"kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, NULL,
+ {"kext-directories", OptionValue::eTypeFileSpecList, false, 0, NULL, {},
"Directories/KDKs to search for kexts in when starting a kernel debug "
- "session."},
- {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+ "session."}};
enum { ePropertySearchForKexts = 0, ePropertyKextDirectories };
@@ -354,6 +350,8 @@ void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
"/Platforms/AppleTVOS.platform/Developer/SDKs");
AddSDKSubdirsToSearchPaths(developer_dir +
"/Platforms/WatchOS.platform/Developer/SDKs");
+ AddSDKSubdirsToSearchPaths(developer_dir +
+ "/Platforms/BridgeOS.platform/Developer/SDKs");
}
if (m_ios_debug_session != eLazyBoolYes) {
AddSDKSubdirsToSearchPaths(developer_dir +
@@ -375,12 +373,15 @@ void PlatformDarwinKernel::CollectKextAndKernelDirectories() {
GetUserSpecifiedDirectoriesToSearch();
// Add simple directory /Applications/Xcode.app/Contents/Developer/../Symbols
- FileSpec possible_dir(developer_dir + "/../Symbols", true);
- if (llvm::sys::fs::is_directory(possible_dir.GetPath()))
+ FileSpec possible_dir(developer_dir + "/../Symbols");
+ FileSystem::Instance().Resolve(possible_dir);
+ if (FileSystem::Instance().IsDirectory(possible_dir))
m_search_directories.push_back(possible_dir);
// Add simple directory of the current working directory
- m_search_directories_no_recursing.push_back(FileSpec(".", true));
+ FileSpec cwd(".");
+ FileSystem::Instance().Resolve(cwd);
+ m_search_directories_no_recursing.push_back(cwd);
}
void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() {
@@ -390,8 +391,8 @@ void PlatformDarwinKernel::GetUserSpecifiedDirectoriesToSearch() {
const uint32_t user_dirs_count = user_dirs.GetSize();
for (uint32_t i = 0; i < user_dirs_count; i++) {
FileSpec dir = user_dirs.GetFileSpecAtIndex(i);
- dir.ResolvePath();
- if (llvm::sys::fs::is_directory(dir.GetPath())) {
+ FileSystem::Instance().Resolve(dir);
+ if (FileSystem::Instance().IsDirectory(dir)) {
m_search_directories.push_back(dir);
}
}
@@ -406,14 +407,14 @@ void PlatformDarwinKernel::AddRootSubdirsToSearchPaths(
// /AppleInternal/Developer/KDKs/*.kdk/...
nullptr};
for (int i = 0; subdirs[i] != nullptr; i++) {
- FileSpec testdir(dir + subdirs[i], true);
- if (llvm::sys::fs::is_directory(testdir.GetPath()))
+ FileSpec testdir(dir + subdirs[i]);
+ FileSystem::Instance().Resolve(testdir);
+ if (FileSystem::Instance().IsDirectory(testdir))
thisp->m_search_directories.push_back(testdir);
}
// Look for kernel binaries in the top level directory, without any recursion
- thisp->m_search_directories_no_recursing.push_back(
- FileSpec(dir + "/", false));
+ thisp->m_search_directories_no_recursing.push_back(FileSpec(dir + "/"));
}
// Given a directory path dir, look for any subdirs named *.kdk and *.sdk
@@ -422,25 +423,26 @@ void PlatformDarwinKernel::AddSDKSubdirsToSearchPaths(const std::string &dir) {
const bool find_directories = true;
const bool find_files = false;
const bool find_other = false;
- FileSpec::EnumerateDirectory(dir.c_str(), find_directories, find_files,
- find_other, FindKDKandSDKDirectoriesInDirectory,
- this);
+ FileSystem::Instance().EnumerateDirectory(
+ dir.c_str(), find_directories, find_files, find_other,
+ FindKDKandSDKDirectoriesInDirectory, this);
}
// Helper function to find *.sdk and *.kdk directories in a given directory.
-FileSpec::EnumerateDirectoryResult
+FileSystem::EnumerateDirectoryResult
PlatformDarwinKernel::FindKDKandSDKDirectoriesInDirectory(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
+ void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
static ConstString g_sdk_suffix = ConstString(".sdk");
static ConstString g_kdk_suffix = ConstString(".kdk");
PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
+ FileSpec file_spec(path);
if (ft == llvm::sys::fs::file_type::directory_file &&
(file_spec.GetFileNameExtension() == g_sdk_suffix ||
file_spec.GetFileNameExtension() == g_kdk_suffix)) {
AddRootSubdirsToSearchPaths(thisp, file_spec.GetPath());
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
// Recursively search trough m_search_directories looking for kext and kernel
@@ -452,7 +454,7 @@ void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
const bool find_directories = true;
const bool find_files = true;
const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
- FileSpec::EnumerateDirectory(
+ FileSystem::Instance().EnumerateDirectory(
dir.GetPath().c_str(), find_directories, find_files, find_other,
GetKernelsAndKextsInDirectoryWithRecursion, this);
}
@@ -462,7 +464,7 @@ void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
const bool find_directories = true;
const bool find_files = true;
const bool find_other = true; // I think eFileTypeSymbolicLink are "other"s.
- FileSpec::EnumerateDirectory(
+ FileSystem::Instance().EnumerateDirectory(
dir.GetPath().c_str(), find_directories, find_files, find_other,
GetKernelsAndKextsInDirectoryNoRecursion, this);
}
@@ -476,25 +478,27 @@ void PlatformDarwinKernel::SearchForKextsAndKernelsRecursively() {
//
// Recurse into any subdirectories found.
-FileSpec::EnumerateDirectoryResult
+FileSystem::EnumerateDirectoryResult
PlatformDarwinKernel::GetKernelsAndKextsInDirectoryWithRecursion(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- return GetKernelsAndKextsInDirectoryHelper(baton, ft, file_spec, true);
+ void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
+ return GetKernelsAndKextsInDirectoryHelper(baton, ft, path, true);
}
-FileSpec::EnumerateDirectoryResult
+FileSystem::EnumerateDirectoryResult
PlatformDarwinKernel::GetKernelsAndKextsInDirectoryNoRecursion(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
- return GetKernelsAndKextsInDirectoryHelper(baton, ft, file_spec, false);
+ void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
+ return GetKernelsAndKextsInDirectoryHelper(baton, ft, path, false);
}
-FileSpec::EnumerateDirectoryResult
+FileSystem::EnumerateDirectoryResult
PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec,
+ void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path,
bool recurse) {
static ConstString g_kext_suffix = ConstString(".kext");
static ConstString g_dsym_suffix = ConstString(".dSYM");
static ConstString g_bundle_suffix = ConstString("Bundle");
+
+ FileSpec file_spec(path);
ConstString file_spec_extension = file_spec.GetFileNameExtension();
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
@@ -526,19 +530,19 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
}
thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
} else if (ft == llvm::sys::fs::file_type::directory_file &&
file_spec_extension == g_kext_suffix) {
AddKextToMap(thisp, file_spec);
// Look to see if there is a PlugIns subdir with more kexts
- FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns", false);
+ FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns");
std::string search_here_too;
- if (llvm::sys::fs::is_directory(contents_plugins.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(contents_plugins)) {
search_here_too = contents_plugins.GetPath();
} else {
- FileSpec plugins(file_spec.GetPath() + "/PlugIns", false);
- if (llvm::sys::fs::is_directory(plugins.GetPath())) {
+ FileSpec plugins(file_spec.GetPath() + "/PlugIns");
+ if (FileSystem::Instance().IsDirectory(plugins)) {
search_here_too = plugins.GetPath();
}
}
@@ -547,13 +551,13 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
const bool find_directories = true;
const bool find_files = false;
const bool find_other = false;
- FileSpec::EnumerateDirectory(
+ FileSystem::Instance().EnumerateDirectory(
search_here_too.c_str(), find_directories, find_files, find_other,
recurse ? GetKernelsAndKextsInDirectoryWithRecursion
: GetKernelsAndKextsInDirectoryNoRecursion,
baton);
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
// Don't recurse into dSYM/kext/bundle directories
if (recurse && file_spec_extension != g_dsym_suffix &&
@@ -561,9 +565,9 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
file_spec_extension != g_bundle_suffix) {
if (log_verbose)
log_verbose->Printf ("PlatformDarwinKernel descending into directory '%s'", file_spec.GetPath().c_str());
- return FileSpec::eEnumerateDirectoryResultEnter;
+ return FileSystem::eEnumerateDirectoryResultEnter;
} else {
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
}
@@ -610,7 +614,7 @@ bool PlatformDarwinKernel::KextHasdSYMSibling(
std::string filename = dsym_fspec.GetFilename().AsCString();
filename += ".dSYM";
dsym_fspec.GetFilename() = ConstString(filename);
- if (llvm::sys::fs::is_directory(dsym_fspec.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(dsym_fspec)) {
return true;
}
// Should probably get the CFBundleExecutable here or call
@@ -623,8 +627,9 @@ bool PlatformDarwinKernel::KextHasdSYMSibling(
kext_bundle_filepath.GetPath() + "/Contents/MacOS/";
deep_bundle_str += executable_name.AsCString();
deep_bundle_str += ".dSYM";
- dsym_fspec.SetFile(deep_bundle_str, true, FileSpec::Style::native);
- if (llvm::sys::fs::is_directory(dsym_fspec.GetPath())) {
+ dsym_fspec.SetFile(deep_bundle_str, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dsym_fspec);
+ if (FileSystem::Instance().IsDirectory(dsym_fspec)) {
return true;
}
@@ -633,11 +638,9 @@ bool PlatformDarwinKernel::KextHasdSYMSibling(
std::string shallow_bundle_str = kext_bundle_filepath.GetPath() + "/";
shallow_bundle_str += executable_name.AsCString();
shallow_bundle_str += ".dSYM";
- dsym_fspec.SetFile(shallow_bundle_str, true, FileSpec::Style::native);
- if (llvm::sys::fs::is_directory(dsym_fspec.GetPath())) {
- return true;
- }
- return false;
+ dsym_fspec.SetFile(shallow_bundle_str, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dsym_fspec);
+ return FileSystem::Instance().IsDirectory(dsym_fspec);
}
// Given a FileSpec of /dir/dir/mach.development.t7004 Return true if a dSYM
@@ -648,10 +651,7 @@ bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) {
std::string filename = kernel_binary.GetFilename().AsCString();
filename += ".dSYM";
kernel_dsym.GetFilename() = ConstString(filename);
- if (llvm::sys::fs::is_directory(kernel_dsym.GetPath())) {
- return true;
- }
- return false;
+ return FileSystem::Instance().IsDirectory(kernel_dsym);
}
Status PlatformDarwinKernel::GetSharedModule(
@@ -710,11 +710,10 @@ Status PlatformDarwinKernel::GetSharedModule(
}
}
- if (kext_bundle_id.compare("mach_kernel") == 0 &&
- module_spec.GetUUID().IsValid()) {
+ if (kext_bundle_id == "mach_kernel" && module_spec.GetUUID().IsValid()) {
// First try all kernel binaries that have a dSYM next to them
for (auto possible_kernel : m_kernel_binaries_with_dsyms) {
- if (possible_kernel.Exists()) {
+ if (FileSystem::Instance().Exists(possible_kernel)) {
ModuleSpec kern_spec(possible_kernel);
kern_spec.GetUUID() = module_spec.GetUUID();
ModuleSP module_sp(new Module(kern_spec));
@@ -750,7 +749,7 @@ Status PlatformDarwinKernel::GetSharedModule(
// Next try all kernel binaries that don't have a dSYM
for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
- if (possible_kernel.Exists()) {
+ if (FileSystem::Instance().Exists(possible_kernel)) {
ModuleSpec kern_spec(possible_kernel);
kern_spec.GetUUID() = module_spec.GetUUID();
ModuleSP module_sp(new Module(kern_spec));
@@ -791,7 +790,7 @@ PlatformDarwinKernel::SearchForExecutablesRecursively(const std::string &dir) {
break;
if (llvm::sys::fs::is_regular_file(*status) &&
llvm::sys::fs::can_execute(it->path()))
- executables.emplace_back(it->path(), false);
+ executables.emplace_back(it->path());
}
return executables;
}
@@ -801,7 +800,7 @@ Status PlatformDarwinKernel::ExamineKextForMatchingUUID(
const ArchSpec &arch, ModuleSP &exe_module_sp) {
for (const auto &exe_file :
SearchForExecutablesRecursively(kext_bundle_path.GetPath())) {
- if (exe_file.Exists()) {
+ if (FileSystem::Instance().Exists(exe_file)) {
ModuleSpec exe_spec(exe_file);
exe_spec.GetUUID() = uuid;
if (!uuid.IsValid()) {
diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
index 7f603cac2bec..201c3dff1795 100644
--- a/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
+++ b/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h
@@ -15,14 +15,10 @@
#if defined(__APPLE__) // This Plugin uses the Mac-specific
// source/Host/macosx/cfcpp utilities
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/FileSystem.h"
-// Project includes
#include "PlatformDarwin.h"
class PlatformDarwinKernel : public PlatformDarwin {
@@ -106,26 +102,25 @@ protected:
void AddSDKSubdirsToSearchPaths(const std::string &dir);
- static lldb_private::FileSpec::EnumerateDirectoryResult
+ static lldb_private::FileSystem::EnumerateDirectoryResult
FindKDKandSDKDirectoriesInDirectory(void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
+ llvm::StringRef path);
void SearchForKextsAndKernelsRecursively();
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetKernelsAndKextsInDirectoryWithRecursion(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
+ static lldb_private::FileSystem::EnumerateDirectoryResult
+ GetKernelsAndKextsInDirectoryWithRecursion(void *baton,
+ llvm::sys::fs::file_type ft,
+ llvm::StringRef path);
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetKernelsAndKextsInDirectoryNoRecursion(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
+ static lldb_private::FileSystem::EnumerateDirectoryResult
+ GetKernelsAndKextsInDirectoryNoRecursion(void *baton,
+ llvm::sys::fs::file_type ft,
+ llvm::StringRef path);
- static lldb_private::FileSpec::EnumerateDirectoryResult
+ static lldb_private::FileSystem::EnumerateDirectoryResult
GetKernelsAndKextsInDirectoryHelper(void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec,
- bool recurse);
+ llvm::StringRef path, bool recurse);
static std::vector<lldb_private::FileSpec>
SearchForExecutablesRecursively(const std::string &dir);
@@ -148,7 +143,7 @@ protected:
const lldb_private::ArchSpec &arch,
lldb::ModuleSP &exe_module_sp);
- // Most of the ivars are assembled under FileSpec::EnumerateDirectory calls
+ // Most of the ivars are assembled under FileSystem::EnumerateDirectory calls
// where the
// function being called for each file/directory must be static. We'll pass a
// this pointer
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 99f603b01f43..4117231c308a 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -10,12 +10,9 @@
#include "PlatformMacOSX.h"
#include "lldb/Host/Config.h"
-// C++ Includes
#include <sstream>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -83,7 +80,7 @@ PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
const bool is_host = false;
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getVendor()) {
case llvm::Triple::Apple:
@@ -93,7 +90,7 @@ PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
#if defined(__APPLE__)
// Only accept "unknown" for vendor if the host is Apple and it "unknown"
// wasn't specified (it was just returned because it was NOT specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
#endif
@@ -218,14 +215,14 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
"SDKs/MacOSX%u.%u.sdk",
xcode_contents_path.c_str(), versions[0],
versions[1]);
- fspec.SetFile(sdk_path.GetString(), false, FileSpec::Style::native);
- if (fspec.Exists())
+ fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native);
+ if (FileSystem::Instance().Exists(fspec))
return ConstString(sdk_path.GetString());
}
if (!default_xcode_sdk.empty()) {
- fspec.SetFile(default_xcode_sdk, false, FileSpec::Style::native);
- if (fspec.Exists())
+ fspec.SetFile(default_xcode_sdk, FileSpec::Style::native);
+ if (FileSystem::Instance().Exists(fspec))
return ConstString(default_xcode_sdk);
}
}
@@ -259,7 +256,7 @@ PlatformMacOSX::GetFileWithUUID(const lldb_private::FileSpec &platform_file,
#endif
std::string remote_os_build;
m_remote_platform_sp->GetOSBuildString(remote_os_build);
- if (local_os_build.compare(remote_os_build) == 0) {
+ if (local_os_build == remote_os_build) {
// same OS version: the local file is good enough
local_file = platform_file;
return Status();
@@ -268,8 +265,8 @@ PlatformMacOSX::GetFileWithUUID(const lldb_private::FileSpec &platform_file,
std::string cache_path(GetLocalCacheDirectory());
std::string module_path(platform_file.GetPath());
cache_path.append(module_path);
- FileSpec module_cache_spec(cache_path, false);
- if (module_cache_spec.Exists()) {
+ FileSpec module_cache_spec(cache_path);
+ if (FileSystem::Instance().Exists(module_cache_spec)) {
local_file = module_cache_spec;
return Status();
}
@@ -284,7 +281,7 @@ PlatformMacOSX::GetFileWithUUID(const lldb_private::FileSpec &platform_file,
err = GetFile(platform_file, module_cache_spec);
if (err.Fail())
return err;
- if (module_cache_spec.Exists()) {
+ if (FileSystem::Instance().Exists(module_cache_spec)) {
local_file = module_cache_spec;
return Status();
} else
diff --git a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index d1e609258d4d..d08029a29f31 100644
--- a/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -10,10 +10,6 @@
#ifndef liblldb_PlatformMacOSX_h_
#define liblldb_PlatformMacOSX_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "PlatformDarwin.h"
class PlatformMacOSX : public PlatformDarwin {
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
new file mode 100644
index 000000000000..fd804d0aaeed
--- /dev/null
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.cpp
@@ -0,0 +1,186 @@
+//===-- PlatformRemoteAppleBridge.cpp -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string>
+#include <vector>
+
+#include "PlatformRemoteAppleBridge.h"
+
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#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/StreamString.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//------------------------------------------------------------------
+/// Default Constructor
+//------------------------------------------------------------------
+PlatformRemoteAppleBridge::PlatformRemoteAppleBridge()
+ : PlatformRemoteDarwinDevice () {}
+
+//------------------------------------------------------------------
+// Static Variables
+//------------------------------------------------------------------
+static uint32_t g_initialize_count = 0;
+
+//------------------------------------------------------------------
+// Static Functions
+//------------------------------------------------------------------
+void PlatformRemoteAppleBridge::Initialize() {
+ PlatformDarwin::Initialize();
+
+ if (g_initialize_count++ == 0) {
+ PluginManager::RegisterPlugin(PlatformRemoteAppleBridge::GetPluginNameStatic(),
+ PlatformRemoteAppleBridge::GetDescriptionStatic(),
+ PlatformRemoteAppleBridge::CreateInstance);
+ }
+}
+
+void PlatformRemoteAppleBridge::Terminate() {
+ if (g_initialize_count > 0) {
+ if (--g_initialize_count == 0) {
+ PluginManager::UnregisterPlugin(PlatformRemoteAppleBridge::CreateInstance);
+ }
+ }
+
+ PlatformDarwin::Terminate();
+}
+
+PlatformSP PlatformRemoteAppleBridge::CreateInstance(bool force,
+ const ArchSpec *arch) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
+ if (log) {
+ const char *arch_name;
+ if (arch && arch->GetArchitectureName())
+ arch_name = arch->GetArchitectureName();
+ else
+ arch_name = "<null>";
+
+ const char *triple_cstr =
+ arch ? arch->GetTriple().getTriple().c_str() : "<null>";
+
+ log->Printf("PlatformRemoteAppleBridge::%s(force=%s, arch={%s,%s})",
+ __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
+ }
+
+ bool create = force;
+ if (!create && arch && arch->IsValid()) {
+ switch (arch->GetMachine()) {
+ case llvm::Triple::aarch64: {
+ const llvm::Triple &triple = arch->GetTriple();
+ llvm::Triple::VendorType vendor = triple.getVendor();
+ switch (vendor) {
+ case llvm::Triple::Apple:
+ create = true;
+ break;
+
+#if defined(__APPLE__)
+ // Only accept "unknown" for the vendor if the host is Apple and
+ // it "unknown" wasn't specified (it was just returned because it
+ // was NOT specified)
+ case llvm::Triple::UnknownVendor:
+ create = !arch->TripleVendorWasSpecified();
+ break;
+
+#endif
+ default:
+ break;
+ }
+ if (create) {
+ switch (triple.getOS()) {
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
+ break;
+
+ default:
+ create = false;
+ break;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+
+ if (create) {
+ if (log)
+ log->Printf("PlatformRemoteAppleBridge::%s() creating platform",
+ __FUNCTION__);
+
+ return lldb::PlatformSP(new PlatformRemoteAppleBridge());
+ }
+
+ if (log)
+ log->Printf("PlatformRemoteAppleBridge::%s() aborting creation of platform",
+ __FUNCTION__);
+
+ return lldb::PlatformSP();
+}
+
+lldb_private::ConstString PlatformRemoteAppleBridge::GetPluginNameStatic() {
+ static ConstString g_name("remote-bridgeos");
+ return g_name;
+}
+
+const char *PlatformRemoteAppleBridge::GetDescriptionStatic() {
+ return "Remote BridgeOS platform plug-in.";
+}
+
+bool PlatformRemoteAppleBridge::GetSupportedArchitectureAtIndex(uint32_t idx,
+ ArchSpec &arch) {
+ ArchSpec system_arch(GetSystemArchitecture());
+
+ const ArchSpec::Core system_core = system_arch.GetCore();
+ switch (system_core) {
+ default:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-bridgeos");
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_arm64:
+ switch (idx) {
+ case 0:
+ arch.SetTriple("arm64-apple-bridgeos");
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ arch.Clear();
+ return false;
+}
+
+
+void PlatformRemoteAppleBridge::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
+{
+ dirnames.clear();
+ dirnames.push_back("BridgeOS DeviceSupport");
+}
+
+std::string PlatformRemoteAppleBridge::GetPlatformName ()
+{
+ return "BridgeOS.platform";
+}
+
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
new file mode 100644
index 000000000000..48f06eee3f01
--- /dev/null
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h
@@ -0,0 +1,73 @@
+//===-- PlatformRemoteAppleBridge.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_PlatformRemoteAppleBridge_h_
+#define liblldb_PlatformRemoteAppleBridge_h_
+
+#include <string>
+
+#include "lldb/Utility/FileSpec.h"
+
+#include "llvm/Support/FileSystem.h"
+
+#include "PlatformRemoteDarwinDevice.h"
+
+class PlatformRemoteAppleBridge : public PlatformRemoteDarwinDevice {
+public:
+ PlatformRemoteAppleBridge();
+
+ ~PlatformRemoteAppleBridge() override = default;
+
+ //------------------------------------------------------------
+ // Class Functions
+ //------------------------------------------------------------
+ static lldb::PlatformSP CreateInstance(bool force,
+ const lldb_private::ArchSpec *arch);
+
+ static void Initialize();
+
+ static void Terminate();
+
+ static lldb_private::ConstString GetPluginNameStatic();
+
+ static const char *GetDescriptionStatic();
+
+ //------------------------------------------------------------
+ // lldb_private::PluginInterface functions
+ //------------------------------------------------------------
+ lldb_private::ConstString GetPluginName() override {
+ return GetPluginNameStatic();
+ }
+
+ uint32_t GetPluginVersion() override { return 1; }
+
+ //------------------------------------------------------------
+ // lldb_private::Platform functions
+ //------------------------------------------------------------
+
+ const char *GetDescription() override { return GetDescriptionStatic(); }
+
+ bool GetSupportedArchitectureAtIndex(uint32_t idx,
+ lldb_private::ArchSpec &arch) override;
+
+protected:
+
+ //------------------------------------------------------------
+ // lldb_private::PlatformRemoteDarwinDevice functions
+ //------------------------------------------------------------
+
+ void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
+
+ std::string GetPlatformName () override;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleBridge);
+};
+
+#endif // liblldb_PlatformRemoteAppleBridge_h_
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
index be4c829a981c..593e888898c4 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.cpp
@@ -7,13 +7,9 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "PlatformRemoteAppleTV.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -101,7 +97,7 @@ PlatformSP PlatformRemoteAppleTV::CreateInstance(bool force,
// Only accept "unknown" for the vendor if the host is Apple and
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
index 08dd231e85ee..d8860a90a460 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h
@@ -10,12 +10,8 @@
#ifndef liblldb_PlatformRemoteAppleTV_h_
#define liblldb_PlatformRemoteAppleTV_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/FileSystem.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
index 6159511d4a18..59e6e19fbffc 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.cpp
@@ -7,13 +7,9 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "PlatformRemoteAppleWatch.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
@@ -96,7 +92,7 @@ PlatformSP PlatformRemoteAppleWatch::CreateInstance(bool force,
// Only accept "unknown" for the vendor if the host is Apple and
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
index 93be55b595f8..ed1cbea62e92 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h
@@ -10,13 +10,9 @@
#ifndef liblldb_PlatformRemoteAppleWatch_h_
#define liblldb_PlatformRemoteAppleWatch_h_
-// C Includes
-// C++ Includes
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/FileSpec.h"
#include "PlatformRemoteDarwinDevice.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
index 930d062fe41e..511bfc20376b 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp
@@ -9,15 +9,12 @@
#include "PlatformRemoteDarwinDevice.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -85,7 +82,7 @@ Status PlatformRemoteDarwinDevice::ResolveExecutable(
// ourselves
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
if (resolved_module_spec.GetArchitecture().IsValid() ||
resolved_module_spec.GetUUID().IsValid()) {
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
@@ -119,7 +116,7 @@ Status PlatformRemoteDarwinDevice::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -139,12 +136,12 @@ Status PlatformRemoteDarwinDevice::ResolveExecutable(
return error;
}
-FileSpec::EnumerateDirectoryResult
+FileSystem::EnumerateDirectoryResult
PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
+ void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
- ->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(file_spec));
- return FileSpec::eEnumerateDirectoryResultNext;
+ ->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(FileSpec(path)));
+ return FileSystem::eEnumerateDirectoryResultNext;
}
bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
@@ -153,7 +150,8 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
if (m_sdk_directory_infos.empty()) {
// A --sysroot option was supplied - add it to our list of SDKs to check
if (m_sdk_sysroot) {
- FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
+ FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString());
+ FileSystem::Instance().Resolve(sdk_sysroot_fspec);
const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
if (log) {
@@ -175,10 +173,10 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
const bool find_other = false;
SDKDirectoryInfoCollection builtin_sdk_directory_infos;
- FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
- find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &builtin_sdk_directory_infos);
+ FileSystem::Instance().EnumerateDirectory(
+ m_device_support_directory, find_directories, find_files, find_other,
+ GetContainedFilesIntoVectorOfStringsCallback,
+ &builtin_sdk_directory_infos);
// Only add SDK directories that have symbols in them, some SDKs only
// contain developer disk images and no symbols, so they aren't useful to
@@ -187,7 +185,7 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
- if (sdk_symbols_symlink_fspec.Exists()) {
+ if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
m_sdk_directory_infos.push_back(sdk_directory_info);
if (log) {
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
@@ -205,22 +203,23 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
const uint32_t num_installed = m_sdk_directory_infos.size();
std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
local_sdk_cache_str += dirname;
- FileSpec local_sdk_cache(local_sdk_cache_str.c_str(), true);
- if (local_sdk_cache.Exists()) {
- if (log) {
+ FileSpec local_sdk_cache(local_sdk_cache_str.c_str());
+ FileSystem::Instance().Resolve(local_sdk_cache);
+ if (FileSystem::Instance().Exists(local_sdk_cache)) {
+ if (log) {
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
"searching %s for additional SDKs",
local_sdk_cache.GetPath().c_str());
- }
+ }
char path[PATH_MAX];
if (local_sdk_cache.GetPath(path, sizeof(path))) {
- FileSpec::EnumerateDirectory(
- path, find_directories, find_files, find_other,
- GetContainedFilesIntoVectorOfStringsCallback,
- &m_sdk_directory_infos);
- const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
- // First try for an exact match of major, minor and update
- for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
+ FileSystem::Instance().EnumerateDirectory(
+ path, find_directories, find_files, find_other,
+ GetContainedFilesIntoVectorOfStringsCallback,
+ &m_sdk_directory_infos);
+ const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
+ // First try for an exact match of major, minor and update
+ for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
m_sdk_directory_infos[i].user_cached = true;
if (log) {
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
@@ -231,6 +230,29 @@ bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
}
}
}
+
+ const char *addtional_platform_dirs = getenv("PLATFORM_SDK_DIRECTORY");
+ if (addtional_platform_dirs) {
+ SDKDirectoryInfoCollection env_var_sdk_directory_infos;
+ FileSystem::Instance().EnumerateDirectory(
+ addtional_platform_dirs, find_directories, find_files, find_other,
+ GetContainedFilesIntoVectorOfStringsCallback,
+ &env_var_sdk_directory_infos);
+ FileSpec sdk_symbols_symlink_fspec;
+ for (const auto &sdk_directory_info : env_var_sdk_directory_infos) {
+ sdk_symbols_symlink_fspec = sdk_directory_info.directory;
+ sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
+ if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
+ m_sdk_directory_infos.push_back(sdk_directory_info);
+ if (log) {
+ log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
+ "added env var SDK directory %s",
+ sdk_symbols_symlink_fspec.GetPath().c_str());
+ }
+ }
+ }
+ }
+
}
}
return !m_sdk_directory_infos.empty();
@@ -395,12 +417,12 @@ bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
- local_file.SetFile(sdkroot_path, false, FileSpec::Style::native);
+ local_file.SetFile(sdkroot_path, FileSpec::Style::native);
if (paths_to_try[i][0] != '\0')
local_file.AppendPathComponent(paths_to_try[i]);
local_file.AppendPathComponent(platform_file_path);
- local_file.ResolvePath();
- if (local_file.Exists()) {
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file)) {
if (log)
log->Printf("Found a copy of %s in the SDK dir %s/%s",
platform_file_path, sdkroot_path.c_str(),
@@ -428,8 +450,9 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
platform_file_path);
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists()) {
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file)) {
if (log) {
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
platform_file_path, os_version_dir);
@@ -440,8 +463,9 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
os_version_dir, platform_file_path);
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists()) {
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file)) {
if (log) {
log->Printf(
"Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
@@ -452,8 +476,9 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
os_version_dir, platform_file_path);
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists()) {
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file)) {
if (log) {
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
platform_file_path, os_version_dir);
@@ -462,7 +487,7 @@ Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
}
}
local_file = platform_file;
- if (local_file.Exists())
+ if (FileSystem::Instance().Exists(local_file))
return error;
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
index 8ddfd51600fd..d32179d6c98e 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h
@@ -10,12 +10,8 @@
#ifndef liblldb_PlatformRemoteDarwinDevice_h_
#define liblldb_PlatformRemoteDarwinDevice_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "PlatformDarwin.h"
#include "lldb/Utility/FileSpec.h"
@@ -84,10 +80,10 @@ protected:
const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
- static lldb_private::FileSpec::EnumerateDirectoryResult
- GetContainedFilesIntoVectorOfStringsCallback(
- void *baton, llvm::sys::fs::file_type ft,
- const lldb_private::FileSpec &file_spec);
+ static lldb_private::FileSystem::EnumerateDirectoryResult
+ GetContainedFilesIntoVectorOfStringsCallback(void *baton,
+ llvm::sys::fs::file_type ft,
+ llvm::StringRef path);
uint32_t FindFileInAllSDKs(const char *platform_file_path,
lldb_private::FileSpecList &file_list);
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 150bfdbfc118..b69d7ea36abf 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -9,10 +9,6 @@
#include "PlatformRemoteiOS.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -75,7 +71,7 @@ PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
}
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
switch (arch->GetMachine()) {
case llvm::Triple::arm:
case llvm::Triple::aarch64:
@@ -91,7 +87,7 @@ PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
// Only accept "unknown" for the vendor if the host is Apple and
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
diff --git a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 975f50b421f1..7e45dc3c2889 100644
--- a/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -10,12 +10,8 @@
#ifndef liblldb_PlatformRemoteiOS_h_
#define liblldb_PlatformRemoteiOS_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "PlatformRemoteDarwinDevice.h"
#include "lldb/Utility/FileSpec.h"
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index 26feec282322..b1d5960bb682 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -10,10 +10,6 @@
#include "PlatformiOSSimulator.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
@@ -80,7 +76,7 @@ PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
}
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
switch (arch->GetMachine()) {
case llvm::Triple::x86_64:
case llvm::Triple::x86: {
@@ -94,7 +90,7 @@ PlatformSP PlatformiOSSimulator::CreateInstance(bool force,
// Only accept "unknown" for the vendor if the host is Apple and it
// "unknown" wasn't specified (it was just returned because it was NOT
// specified)
- case llvm::Triple::UnknownArch:
+ case llvm::Triple::UnknownVendor:
create = !arch->TripleVendorWasSpecified();
break;
#endif
@@ -196,7 +192,7 @@ Status PlatformiOSSimulator::ResolveExecutable(
// ourselves
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
if (resolved_module_spec.GetArchitecture().IsValid()) {
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
NULL, NULL, NULL);
@@ -234,7 +230,7 @@ Status PlatformiOSSimulator::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -253,18 +249,19 @@ Status PlatformiOSSimulator::ResolveExecutable(
return error;
}
-static FileSpec::EnumerateDirectoryResult
+static FileSystem::EnumerateDirectoryResult
EnumerateDirectoryCallback(void *baton, llvm::sys::fs::file_type ft,
- const FileSpec &file_spec) {
+ llvm::StringRef path) {
if (ft == llvm::sys::fs::file_type::directory_file) {
+ FileSpec file_spec(path);
const char *filename = file_spec.GetFilename().GetCString();
if (filename &&
strncmp(filename, "iPhoneSimulator", strlen("iPhoneSimulator")) == 0) {
::snprintf((char *)baton, PATH_MAX, "%s", filename);
- return FileSpec::eEnumerateDirectoryResultQuit;
+ return FileSystem::eEnumerateDirectoryResultQuit;
}
}
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSystem::eEnumerateDirectoryResultNext;
}
const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
@@ -282,9 +279,9 @@ const char *PlatformiOSSimulator::GetSDKDirectoryAsCString() {
bool find_directories = true;
bool find_files = false;
bool find_other = false;
- FileSpec::EnumerateDirectory(sdks_directory, find_directories, find_files,
- find_other, EnumerateDirectoryCallback,
- sdk_dirname);
+ FileSystem::Instance().EnumerateDirectory(
+ sdks_directory, find_directories, find_files, find_other,
+ EnumerateDirectoryCallback, sdk_dirname);
if (sdk_dirname[0]) {
m_sdk_directory = sdks_directory;
@@ -320,13 +317,15 @@ Status PlatformiOSSimulator::GetSymbolFile(const FileSpec &platform_file,
platform_file_path);
// First try in the SDK and see if the file is in there
- local_file.SetFile(resolved_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(resolved_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
// Else fall back to the actual path itself
- local_file.SetFile(platform_file_path, true, FileSpec::Style::native);
- if (local_file.Exists())
+ local_file.SetFile(platform_file_path, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(local_file);
+ if (FileSystem::Instance().Exists(local_file))
return error;
}
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
index 2d81d6229f73..4ac43a4dde28 100644
--- a/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
+++ b/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
@@ -10,13 +10,9 @@
#ifndef liblldb_PlatformiOSSimulator_h_
#define liblldb_PlatformiOSSimulator_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "PlatformAppleSimulator.h"
class PlatformiOSSimulator : public PlatformAppleSimulator {
diff --git a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
index 083e2d6c5687..bec35aaaf33b 100644
--- a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
+++ b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.h
@@ -11,19 +11,15 @@
#ifndef liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
#define liblldb_PlatformiOSSimulatorCoreSimulatorSupport_h_
-// C Includes
-// C++ Includes
#include <functional>
#include <ostream>
#include <string>
#include <vector>
-// Other libraries and framework includes
#ifdef __APPLE__
#include <objc/objc.h>
#else
typedef void *id;
#endif
-// Project includes
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/ConstString.h"
diff --git a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
index 4516a66ee8ca..a601e27dc8a1 100644
--- a/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
+++ b/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm
@@ -409,7 +409,7 @@ static Status HandleFileAction(ProcessLaunchInfo &launch_info,
// Check in case our file action open wants to open the slave
const char *slave_path = launch_info.GetPTY().GetSlaveName(NULL, 0);
if (slave_path) {
- FileSpec slave_spec(slave_path, false);
+ FileSpec slave_spec(slave_path);
if (file_spec == slave_spec) {
int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor();
if (slave_fd == PseudoTerminal::invalid_fd)
@@ -591,7 +591,7 @@ void CoreSimulatorSupport::DeviceSet::ForEach(
std::function<bool(const Device &)> f) {
const size_t n = GetNumDevices();
for (NSUInteger i = 0; i < n; ++i) {
- if (f(GetDeviceAtIndex(i)) == false)
+ if (!f(GetDeviceAtIndex(i)))
break;
}
}
diff --git a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index 3aa8ecb4c228..aadcf961c729 100644
--- a/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -10,23 +10,19 @@
#include "PlatformNetBSD.h"
#include "lldb/Host/Config.h"
-// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -50,7 +46,7 @@ PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) {
arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getOS()) {
case llvm::Triple::NetBSD:
@@ -271,8 +267,8 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
if (target == nullptr) {
LLDB_LOG(log, "creating new target");
TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- nullptr, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
if (error.Fail()) {
LLDB_LOG(log, "failed to create new target: {0}", error);
return process_sp;
@@ -291,8 +287,8 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// Now create the gdb-remote process.
LLDB_LOG(log, "having target create process with gdb-remote plugin");
- process_sp = target->CreateProcess(
- launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr);
+ process_sp =
+ target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr);
if (!process_sp) {
error.SetErrorString("CreateProcess() failed for gdb-remote process");
diff --git a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
index 10ca8fbfbdd7..7358acb61f79 100644
--- a/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
+++ b/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp
@@ -10,23 +10,19 @@
#include "PlatformOpenBSD.h"
#include "lldb/Host/Config.h"
-// C Includes
#include <stdio.h>
#ifndef LLDB_DISABLE_POSIX
#include <sys/utsname.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
@@ -50,7 +46,7 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) {
arch ? arch->GetTriple().getTriple() : "<null>");
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getOS()) {
case llvm::Triple::OpenBSD:
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index 5e7ffe71918e..bfa1376d3151 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -9,10 +9,6 @@
#include "PlatformPOSIX.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -128,23 +124,25 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
if (IsHost()) {
// If we have "ls" as the exe_file, resolve the executable location based
// on the current path variables
- if (!resolved_module_spec.GetFileSpec().Exists()) {
+ if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true,
+ resolved_module_spec.GetFileSpec().SetFile(exe_path,
FileSpec::Style::native);
+ FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
}
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
+ if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
+ FileSystem::Instance().ResolveExecutableLocation(
+ resolved_module_spec.GetFileSpec());
// Resolve any executable within a bundle on MacOSX
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists())
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
error.Clear();
else {
- const uint32_t permissions =
- resolved_module_spec.GetFileSpec().GetPermissions();
+ const uint32_t permissions = FileSystem::Instance().GetPermissions(
+ resolved_module_spec.GetFileSpec());
if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
error.SetErrorStringWithFormat(
"executable '%s' is not readable",
@@ -166,7 +164,7 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
// Resolve any executable within a bundle on MacOSX
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists())
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
error.Clear();
else
error.SetErrorStringWithFormat("the platform is not currently "
@@ -237,7 +235,8 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(
+ resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -455,7 +454,7 @@ lldb::user_id_t PlatformPOSIX::GetFileSize(const FileSpec &file_spec) {
Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) {
if (IsHost())
- return FileSystem::Symlink(src, dst);
+ return FileSystem::Instance().Symlink(src, dst);
else if (m_remote_platform_sp)
return m_remote_platform_sp->CreateSymlink(src, dst);
else
@@ -464,7 +463,7 @@ Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) {
bool PlatformPOSIX::GetFileExists(const FileSpec &file_spec) {
if (IsHost())
- return file_spec.Exists();
+ return FileSystem::Instance().Exists(file_spec);
else if (m_remote_platform_sp)
return m_remote_platform_sp->GetFileExists(file_spec);
else
@@ -813,8 +812,8 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
if (target == NULL) {
TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- NULL, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, NULL, new_target_sp);
target = new_target_sp.get();
if (log)
log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__);
@@ -1244,7 +1243,8 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
// don't do the work to trap them.
options.SetTimeout(std::chrono::seconds(2));
-
+ options.SetIsForUtilityExpr(true);
+
Value return_value;
// Fetch the clang types we will need:
ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
@@ -1281,8 +1281,7 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
std::string name_string;
process->ReadCStringFromMemory(buffer_addr, name_string, utility_error);
if (utility_error.Success())
- loaded_image->SetFile(name_string, false,
- llvm::sys::path::Style::posix);
+ loaded_image->SetFile(name_string, llvm::sys::path::Style::posix);
}
return process->AddImageToken(token);
}
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index cc6f7299c194..97333ef1eb7c 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -10,13 +10,9 @@
#ifndef liblldb_PlatformPOSIX_h_
#define liblldb_PlatformPOSIX_h_
-// C Includes
-// C++ Includes
#include <map>
#include <memory>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Interpreter/Options.h"
#include "lldb/Target/Platform.h"
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp
index 45e906f88e00..685d49a73a77 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -9,16 +9,12 @@
#include "PlatformWindows.h"
-// C Includes
#include <stdio.h>
#if defined(_WIN32)
#include "lldb/Host/windows/windows.h"
#include <winsock2.h>
#endif
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
@@ -71,7 +67,7 @@ PlatformSP PlatformWindows::CreateInstance(bool force,
const bool is_host = false;
bool create = force;
- if (create == false && arch && arch->IsValid()) {
+ if (!create && arch && arch->IsValid()) {
const llvm::Triple &triple = arch->GetTriple();
switch (triple.getVendor()) {
case llvm::Triple::PC:
@@ -192,16 +188,18 @@ Status PlatformWindows::ResolveExecutable(
if (IsHost()) {
// if we cant resolve the executable loation based on the current path
// variables
- if (!resolved_module_spec.GetFileSpec().Exists()) {
+ if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
- resolved_module_spec.GetFileSpec().SetFile(exe_path, true,
+ resolved_module_spec.GetFileSpec().SetFile(exe_path,
FileSpec::Style::native);
+ FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
}
- if (!resolved_module_spec.GetFileSpec().Exists())
- resolved_module_spec.GetFileSpec().ResolveExecutableLocation();
+ if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
+ FileSystem::Instance().ResolveExecutableLocation(
+ resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists())
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
error.Clear();
else {
ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
@@ -215,7 +213,7 @@ Status PlatformWindows::ResolveExecutable(
} else {
// We may connect to a process and use the provided executable (Don't use
// local $PATH).
- if (resolved_module_spec.GetFileSpec().Exists())
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
error.Clear();
else
error.SetErrorStringWithFormat("the platform is not currently "
@@ -262,7 +260,8 @@ Status PlatformWindows::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(
+ resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -438,9 +437,8 @@ ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info,
ProcessAttachInfo attach_info(launch_info);
return Attach(attach_info, debugger, target, error);
} else {
- ProcessSP process_sp =
- target->CreateProcess(launch_info.GetListenerForProcess(debugger),
- launch_info.GetProcessPluginName(), nullptr);
+ ProcessSP process_sp = target->CreateProcess(
+ launch_info.GetListener(), launch_info.GetProcessPluginName(), nullptr);
// We need to launch and attach to the process.
launch_info.GetFlags().Set(eLaunchFlagDebug);
@@ -470,8 +468,8 @@ lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info,
FileSpec emptyFileSpec;
ArchSpec emptyArchSpec;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- nullptr, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
target = new_target_sp.get();
}
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.h b/source/Plugins/Platform/Windows/PlatformWindows.h
index 3a15271c5762..f7f55049e4e7 100644
--- a/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -10,10 +10,6 @@
#ifndef liblldb_PlatformWindows_h_
#define liblldb_PlatformWindows_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Platform.h"
namespace lldb_private {
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 348bb825a5c5..f6ace706ca3f 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -10,9 +10,6 @@
#include "PlatformRemoteGDBServer.h"
#include "lldb/Host/Config.h"
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
@@ -43,7 +40,7 @@ static bool g_initialized = false;
void PlatformRemoteGDBServer::Initialize() {
Platform::Initialize();
- if (g_initialized == false) {
+ if (!g_initialized) {
g_initialized = true;
PluginManager::RegisterPlugin(
PlatformRemoteGDBServer::GetPluginNameStatic(),
@@ -107,7 +104,7 @@ Status PlatformRemoteGDBServer::ResolveExecutable(
// Resolve any executable within an apk on Android?
// Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
- if (resolved_module_spec.GetFileSpec().Exists() ||
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) ||
module_spec.GetUUID().IsValid()) {
if (resolved_module_spec.GetArchitecture().IsValid() ||
resolved_module_spec.GetUUID().IsValid()) {
@@ -142,7 +139,7 @@ Status PlatformRemoteGDBServer::ResolveExecutable(
}
if (error.Fail() || !exe_module_sp) {
- if (resolved_module_spec.GetFileSpec().Readable()) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
error.SetErrorStringWithFormat(
"'%s' doesn't contain any '%s' platform architectures: %s",
resolved_module_spec.GetFileSpec().GetPath().c_str(),
@@ -488,8 +485,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
if (target == NULL) {
TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- NULL, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, NULL, new_target_sp);
target = new_target_sp.get();
} else
error.Clear();
@@ -499,8 +496,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess(
// The darwin always currently uses the GDB remote debugger plug-in
// so even when debugging locally we are debugging remotely!
- process_sp = target->CreateProcess(
- launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL);
+ process_sp = target->CreateProcess(launch_info.GetListener(),
+ "gdb-remote", NULL);
if (process_sp) {
error = process_sp->ConnectRemote(nullptr, connect_url.c_str());
@@ -574,8 +571,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach(
if (target == NULL) {
TargetSP new_target_sp;
- error = debugger.GetTargetList().CreateTarget(debugger, "", "", false,
- NULL, new_target_sp);
+ error = debugger.GetTargetList().CreateTarget(
+ debugger, "", "", eLoadDependentsNo, NULL, new_target_sp);
target = new_target_sp.get();
} else
error.Clear();
diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index a31933b5d9b0..7abb33423bc1 100644
--- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -11,12 +11,8 @@
#ifndef liblldb_PlatformRemoteGDBServer_h_
#define liblldb_PlatformRemoteGDBServer_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
#include "lldb/Target/Platform.h"
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
index 3505443abcb0..70d9a5248fd9 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp
@@ -19,10 +19,10 @@
// C++ includes
// LLDB includes
-#include "lldb/Core/State.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "CFBundle.h"
@@ -63,12 +63,13 @@ Status NativeProcessProtocol::Launch(
// Verify the working directory is valid if one was specified.
FileSpec working_dir(launch_info.GetWorkingDirectory());
- if (working_dir &&
- (!working_dir.ResolvePath() ||
- !llvm::sys::fs::is_directory(working_dir.GetPath())) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
+ if (working_dir) {
+ FileInstance::Instance().Resolve(working_dir);
+ if (!FileSystem::Instance().IsDirectory(working_dir)) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
working_dir.GetCString());
- return error;
+ return error;
+ }
}
// Launch the inferior.
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
index 0b186fd7d80c..9abdd5360eba 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.h
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -21,7 +21,6 @@
#include <mutex>
#include <unordered_set>
-// Other libraries and framework includes
#include "lldb/Host/Debug.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Pipe.h"
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index 3576a7f26f86..fce0be22678e 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <pthread.h>
#include <pthread_np.h>
@@ -16,12 +15,9 @@
#include <sys/types.h>
#include <sys/user.h>
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/State.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/State.h"
-// Project includes
#include "FreeBSDThread.h"
#include "POSIXStopInfo.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
@@ -42,7 +38,6 @@
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThread.h"
@@ -50,6 +45,7 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadSpec.h"
+#include "lldb/Utility/State.h"
#include "llvm/ADT/SmallString.h"
using namespace lldb;
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
index c93cc4fbfd73..a8559fe8b2ca 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.h
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.h
@@ -10,11 +10,9 @@
#ifndef liblldb_FreeBSDThread_H_
#define liblldb_FreeBSDThread_H_
-// C++ Includes
#include <memory>
#include <string>
-// Other libraries and framework includes
#include "RegisterContextPOSIX.h"
#include "lldb/Target/Thread.h"
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index fa0bcea8f6bd..a13d4bcc4ecb 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -8,7 +8,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <pthread.h>
#include <pthread_np.h>
@@ -18,18 +17,17 @@
#include <sys/user.h>
#include <machine/elf.h>
-// C++ Includes
#include <mutex>
#include <unordered_map>
-// Other libraries and framework includes
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/State.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
#include "FreeBSDThread.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
@@ -38,13 +36,11 @@
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
-// Other libraries and framework includes
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
@@ -52,6 +48,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/State.h"
#include "lldb/Host/posix/Fcntl.h"
@@ -287,7 +284,7 @@ bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target_sp->GetExecutableModule());
if (exe_module_sp.get())
- return exe_module_sp->GetFileSpec().Exists();
+ return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
// If there is no executable module, we return true since we might be
// preparing to attach.
return true;
@@ -335,7 +332,7 @@ ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid,
GetTarget().SetArchitecture(module_arch);
// Initialize the target module list
- GetTarget().SetExecutableModule(exe_module_sp, true);
+ GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes);
SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
@@ -373,12 +370,13 @@ Status ProcessFreeBSD::DoLaunch(Module *module,
assert(m_monitor == NULL);
FileSpec working_dir = launch_info.GetWorkingDirectory();
- namespace fs = llvm::sys::fs;
- if (working_dir && (!working_dir.ResolvePath() ||
- !fs::is_directory(working_dir.GetPath()))) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
+ if (working_dir) {
+ FileSystem::Instance().Resolve(working_dir);
+ if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) {
+ error.SetErrorStringWithFormat("No such file or directory: %s",
working_dir.GetCString());
- return error;
+ return error;
+ }
}
SetPrivateState(eStateLaunching);
@@ -390,8 +388,7 @@ Status ProcessFreeBSD::DoLaunch(Module *module,
FileSpec stdout_file_spec{};
FileSpec stderr_file_spec{};
- const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0),
- false};
+ const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)};
file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
stdin_file_spec =
@@ -519,7 +516,7 @@ void ProcessFreeBSD::DoDidExec() {
executable_search_paths.GetSize() ? &executable_search_paths : NULL);
if (!error.Success())
return;
- target->SetExecutableModule(exe_module_sp, true);
+ target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
}
}
}
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 51fdf2e5ef33..617ae3030f10 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <poll.h>
#include <signal.h>
@@ -19,16 +18,14 @@
#include <sys/wait.h>
#include <unistd.h>
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "llvm/Support/Errno.h"
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
index 1d3e2d746fa9..ca7c4e03966c 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.h
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.h
@@ -10,14 +10,11 @@
#ifndef liblldb_ProcessMonitor_H_
#define liblldb_ProcessMonitor_H_
-// C Includes
#include <semaphore.h>
#include <signal.h>
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
#include "lldb/Host/HostThread.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-types.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index b1b44e71de46..32973abd9207 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -10,9 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_H_
#define liblldb_RegisterContextPOSIX_H_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/ArchSpec.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
index 8ddc253aea5d..0642a30ade70 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp
@@ -7,9 +7,9 @@
//
//===---------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
index 93ffeb5ea79b..b35ee18d6a96 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp
@@ -7,9 +7,9 @@
//
//===---------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
#include "ProcessFreeBSD.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
index 734167e1fc98..17df44cf85ee 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
#include "ProcessFreeBSD.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
index 5cc6cd290629..a8d75963ea6b 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "ProcessFreeBSD.h"
#include "ProcessMonitor.h"
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 7db7f803b371..68fd5ac13bb0 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
#include "Plugins/Process/FreeBSD/ProcessMonitor.h"
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 3fb886e1c7a3..8c6c95380e81 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -9,29 +9,23 @@
#include "NativeProcessLinux.h"
-// C Includes
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
-// C++ Includes
#include <fstream>
#include <mutex>
#include <sstream>
#include <string>
#include <unordered_map>
-// Other libraries and framework includes
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Host/linux/Uio.h"
@@ -41,6 +35,8 @@
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
#include "llvm/Support/Errno.h"
@@ -49,6 +45,7 @@
#include "NativeThreadLinux.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/LinuxProcMaps.h"
#include "Procfs.h"
#include <linux/unistd.h>
@@ -759,9 +756,7 @@ void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
// Mark the thread as stopped at breakpoint.
thread.SetStoppedByBreakpoint();
- Status error = FixupBreakpointPCAsNeeded(thread);
- if (error.Fail())
- LLDB_LOG(log, "pid = {0} fixup: {1}", thread.GetID(), error);
+ FixupBreakpointPCAsNeeded(thread);
if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
m_threads_stepping_with_breakpoint.end())
@@ -1238,90 +1233,6 @@ Status NativeProcessLinux::Kill() {
return error;
}
-static Status
-ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef &maps_line,
- MemoryRegionInfo &memory_region_info) {
- memory_region_info.Clear();
-
- StringExtractor line_extractor(maps_line);
-
- // Format: {address_start_hex}-{address_end_hex} perms offset dev inode
- // pathname perms: rwxp (letter is present if set, '-' if not, final
- // character is p=private, s=shared).
-
- // Parse out the starting address
- lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
-
- // Parse out hyphen separating start and end address from range.
- if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
- return Status(
- "malformed /proc/{pid}/maps entry, missing dash between address range");
-
- // Parse out the ending address
- lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
-
- // Parse out the space after the address.
- if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
- return Status(
- "malformed /proc/{pid}/maps entry, missing space after range");
-
- // Save the range.
- memory_region_info.GetRange().SetRangeBase(start_address);
- memory_region_info.GetRange().SetRangeEnd(end_address);
-
- // Any memory region in /proc/{pid}/maps is by definition mapped into the
- // process.
- memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
-
- // Parse out each permission entry.
- if (line_extractor.GetBytesLeft() < 4)
- return Status("malformed /proc/{pid}/maps entry, missing some portion of "
- "permissions");
-
- // Handle read permission.
- const char read_perm_char = line_extractor.GetChar();
- if (read_perm_char == 'r')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
- else if (read_perm_char == '-')
- memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
- else
- return Status("unexpected /proc/{pid}/maps read permission char");
-
- // Handle write permission.
- const char write_perm_char = line_extractor.GetChar();
- if (write_perm_char == 'w')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
- else if (write_perm_char == '-')
- memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
- else
- return Status("unexpected /proc/{pid}/maps write permission char");
-
- // Handle execute permission.
- const char exec_perm_char = line_extractor.GetChar();
- if (exec_perm_char == 'x')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
- else if (exec_perm_char == '-')
- memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
- else
- return Status("unexpected /proc/{pid}/maps exec permission char");
-
- line_extractor.GetChar(); // Read the private bit
- line_extractor.SkipSpaces(); // Skip the separator
- line_extractor.GetHexMaxU64(false, 0); // Read the offset
- line_extractor.GetHexMaxU64(false, 0); // Read the major device number
- line_extractor.GetChar(); // Read the device id separator
- line_extractor.GetHexMaxU64(false, 0); // Read the major device number
- line_extractor.SkipSpaces(); // Skip the separator
- line_extractor.GetU64(0, 10); // Read the inode number
-
- line_extractor.SkipSpaces();
- const char *name = line_extractor.Peek();
- if (name)
- memory_region_info.SetName(name);
-
- return Status();
-}
-
Status NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) {
// FIXME review that the final memory region returned extends to the end of
@@ -1407,22 +1318,23 @@ Status NativeProcessLinux::PopulateMemoryRegionCache() {
m_supports_mem_region = LazyBool::eLazyBoolNo;
return BufferOrError.getError();
}
- StringRef Rest = BufferOrError.get()->getBuffer();
- while (! Rest.empty()) {
- StringRef Line;
- std::tie(Line, Rest) = Rest.split('\n');
- MemoryRegionInfo info;
- const Status parse_error =
- ParseMemoryRegionInfoFromProcMapsLine(Line, info);
- if (parse_error.Fail()) {
- LLDB_LOG(log, "failed to parse proc maps line '{0}': {1}", Line,
- parse_error);
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- return parse_error;
- }
- m_mem_region_cache.emplace_back(
- info, FileSpec(info.GetName().GetCString(), true));
- }
+ Status Result;
+ ParseLinuxMapRegions(BufferOrError.get()->getBuffer(),
+ [&](const MemoryRegionInfo &Info, const Status &ST) {
+ if (ST.Success()) {
+ FileSpec file_spec(Info.GetName().GetCString());
+ FileSystem::Instance().Resolve(file_spec);
+ m_mem_region_cache.emplace_back(Info, file_spec);
+ return true;
+ } else {
+ m_supports_mem_region = LazyBool::eLazyBoolNo;
+ LLDB_LOG(log, "failed to parse proc maps: {0}", ST);
+ Result = ST;
+ return false;
+ }
+ });
+ if (Result.Fail())
+ return Result;
if (m_mem_region_cache.empty()) {
// No entries after attempting to read them. This shouldn't happen if
@@ -1502,40 +1414,6 @@ size_t NativeProcessLinux::UpdateThreads() {
return m_threads.size();
}
-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};
-
- switch (m_arch.GetMachine()) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode));
- return Status();
-
- case llvm::Triple::systemz:
- actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
- return Status();
-
- case llvm::Triple::arm:
- case llvm::Triple::aarch64:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::ppc64le:
- // On these architectures the PC don't get updated for breakpoint hits
- actual_opcode_size = 0;
- return Status();
-
- default:
- assert(false && "CPU type not supported!");
- return Status("CPU type not supported");
- }
-}
-
Status NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) {
if (hardware)
@@ -1551,74 +1429,26 @@ Status NativeProcessLinux::RemoveBreakpoint(lldb::addr_t addr, bool hardware) {
return NativeProcessProtocol::RemoveBreakpoint(addr);
}
-Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
- size_t trap_opcode_size_hint, size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) {
- // FIXME put this behind a breakpoint protocol class that can be set per
- // architecture. Need MIPS support here.
- static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
+llvm::Expected<llvm::ArrayRef<uint8_t>>
+NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
// The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
// linux kernel does otherwise.
- static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
- static const uint8_t g_i386_opcode[] = {0xCC};
- static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
- static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
- static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
- static const uint8_t g_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:
- trap_opcode_bytes = g_aarch64_opcode;
- actual_opcode_size = sizeof(g_aarch64_opcode);
- return Status();
+ static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
+ static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
+ switch (GetArchitecture().GetMachine()) {
case llvm::Triple::arm:
- switch (trap_opcode_size_hint) {
+ switch (size_hint) {
case 2:
- trap_opcode_bytes = g_thumb_breakpoint_opcode;
- actual_opcode_size = sizeof(g_thumb_breakpoint_opcode);
- return Status();
+ return llvm::makeArrayRef(g_thumb_opcode);
case 4:
- trap_opcode_bytes = g_arm_breakpoint_opcode;
- actual_opcode_size = sizeof(g_arm_breakpoint_opcode);
- return Status();
+ return llvm::makeArrayRef(g_arm_opcode);
default:
- assert(false && "Unrecognised trap opcode size hint!");
- return Status("Unrecognised trap opcode size hint!");
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Unrecognised trap opcode size hint!");
}
-
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- trap_opcode_bytes = g_i386_opcode;
- actual_opcode_size = sizeof(g_i386_opcode);
- return Status();
-
- case llvm::Triple::mips:
- case llvm::Triple::mips64:
- trap_opcode_bytes = g_mips64_opcode;
- actual_opcode_size = sizeof(g_mips64_opcode);
- return Status();
-
- case llvm::Triple::mipsel:
- case llvm::Triple::mips64el:
- trap_opcode_bytes = g_mips64el_opcode;
- actual_opcode_size = sizeof(g_mips64el_opcode);
- return Status();
-
- case llvm::Triple::systemz:
- trap_opcode_bytes = g_s390x_opcode;
- 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");
+ return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
}
}
@@ -1677,15 +1507,6 @@ Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
return Status();
}
-Status NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
- size_t size,
- size_t &bytes_read) {
- Status error = ReadMemory(addr, buf, size, bytes_read);
- if (error.Fail())
- return error;
- return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
-}
-
Status NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf,
size_t size, size_t &bytes_written) {
const unsigned char *src = static_cast<const unsigned char *>(buf);
@@ -1810,90 +1631,14 @@ NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
return static_cast<NativeThreadLinux &>(*m_threads.back());
}
-Status
-NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- Status error;
-
- // Find out the size of a breakpoint (might depend on where we are in the
- // code).
- NativeRegisterContext &context = thread.GetRegisterContext();
-
- uint32_t breakpoint_size = 0;
- error = GetSoftwareBreakpointPCOffset(breakpoint_size);
- if (error.Fail()) {
- LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error);
- return error;
- } else
- LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
-
- // First try probing for a breakpoint at a software breakpoint location: PC -
- // breakpoint size.
- 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.
- if (breakpoint_addr >= breakpoint_size)
- breakpoint_addr -= breakpoint_size;
- }
-
- // Check if we stopped because of a breakpoint.
- NativeBreakpointSP breakpoint_sp;
- error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
- if (!error.Success() || !breakpoint_sp) {
- // We didn't find one at a software probe location. Nothing to do.
- LLDB_LOG(log,
- "pid {0} no lldb breakpoint found at current pc with "
- "adjustment: {1}",
- GetID(), breakpoint_addr);
- return Status();
- }
-
- // If the breakpoint is not a software breakpoint, nothing to do.
- if (!breakpoint_sp->IsSoftwareBreakpoint()) {
- LLDB_LOG(
- log,
- "pid {0} breakpoint found at {1:x}, not software, nothing to adjust",
- GetID(), breakpoint_addr);
- return Status();
- }
-
- //
- // We have a software breakpoint and need to adjust the PC.
- //
-
- // Sanity check.
- if (breakpoint_size == 0) {
- // Nothing to do! How did we get here?
- LLDB_LOG(log,
- "pid {0} breakpoint found at {1:x}, it is software, but the "
- "size is zero, nothing to do (unexpected)",
- GetID(), breakpoint_addr);
- return Status();
- }
-
- // 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.SetPC(breakpoint_addr);
- if (error.Fail()) {
- LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
- thread.GetID(), error);
- return error;
- }
-
- return error;
-}
-
Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
FileSpec &file_spec) {
Status error = PopulateMemoryRegionCache();
if (error.Fail())
return error;
- FileSpec module_file_spec(module_path, true);
+ FileSpec module_file_spec(module_path);
+ FileSystem::Instance().Resolve(module_file_spec);
file_spec.Clear();
for (const auto &it : m_mem_region_cache) {
@@ -1913,7 +1658,7 @@ Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
if (error.Fail())
return error;
- FileSpec file(file_name, false);
+ FileSpec file(file_name);
for (const auto &it : m_mem_region_cache) {
if (it.second == file) {
load_addr = it.first.GetRange().GetRangeBase();
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index 1c2f786e8d69..69f2b528d330 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -71,9 +71,6 @@ public:
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
size_t &bytes_read) override;
- Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
size_t &bytes_written) override;
@@ -134,13 +131,8 @@ public:
bool SupportHardwareSingleStepping() const;
protected:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol protected interface
- // ---------------------------------------------------------------------
- Status
- GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
- size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) override;
+ llvm::Expected<llvm::ArrayRef<uint8_t>>
+ GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
private:
MainLoop::SignalHandleUP m_sigchld_handle;
@@ -190,10 +182,6 @@ private:
NativeThreadLinux &AddThread(lldb::tid_t thread_id);
- Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
-
- Status FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
-
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index c8a8355f9cb9..79f635c88985 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -9,10 +9,10 @@
#include "NativeRegisterContextLinux.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/Host/linux/Ptrace.h"
+#include "lldb/Utility/RegisterValue.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 749291684620..09d3a12942f0 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -15,9 +15,9 @@
#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/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include <elf.h>
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 41fe446f728c..9a392edbe9ef 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -12,14 +12,11 @@
#include "NativeRegisterContextLinux_arm.h"
#include "NativeRegisterContextLinux_arm64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index 69194b3c0663..d641056a0440 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -11,22 +11,19 @@
#include "NativeRegisterContextLinux_mips64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Linux/Procfs.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
index 6aa4af64ab51..da51fda1c80b 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -14,10 +14,10 @@
#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/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index 36da2b001054..1bc916b69bcd 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -11,10 +11,10 @@
#include "NativeRegisterContextLinux_s390x.h"
#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 87f4b8da053e..50bf29b094df 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -11,10 +11,10 @@
#include "NativeRegisterContextLinux_x86_64.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 4ab2a9ae6245..b64689c9d17b 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -16,12 +16,12 @@
#include "NativeRegisterContextLinux.h"
#include "SingleStepCheck.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostNativeThread.h"
#include "lldb/Host/linux/Ptrace.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/SmallString.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
index 116155d9a232..8908108eff4b 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
@@ -9,25 +9,21 @@
#include "CommunicationKDP.h"
-// C Includes
#include <errno.h>
#include <limits.h>
#include <string.h>
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Core/DumpDataExtractor.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/UUID.h"
-// Project includes
#include "ProcessKDPLog.h"
using namespace lldb;
@@ -467,19 +463,13 @@ lldb_private::UUID CommunicationKDP::GetUUID() {
bool CommunicationKDP::RemoteIsEFI() {
if (GetKernelVersion() == NULL)
return false;
- if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0)
- return true;
- else
- return false;
+ return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0;
}
bool CommunicationKDP::RemoteIsDarwinKernel() {
if (GetKernelVersion() == NULL)
return false;
- if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
- return true;
- else
- return false;
+ return m_kernel_version.find("Darwin Kernel") != std::string::npos;
}
lldb::addr_t CommunicationKDP::GetLoadAddress() {
@@ -1262,9 +1252,7 @@ bool CommunicationKDP::SendRequestResume() {
request_packet.PutHex32(GetCPUMask());
DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet))
- return true;
- return false;
+ return SendRequestAndGetReply(command, request_packet, reply_packet);
}
bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) {
@@ -1297,7 +1285,5 @@ bool CommunicationKDP::SendRequestSuspend() {
const uint32_t command_length = 8;
MakeRequestPacketHeader(command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet))
- return true;
- return false;
+ return SendRequestAndGetReply(command, request_packet, reply_packet);
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
index afac6601a56b..64bfe5514735 100644
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
@@ -10,18 +10,14 @@
#ifndef liblldb_CommunicationKDP_h_
#define liblldb_CommunicationKDP_h_
-// C Includes
-// C++ Includes
#include <list>
#include <mutex>
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Communication.h"
-#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamBuffer.h"
-#include "lldb/Host/Predicate.h"
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/Predicate.h"
#include "lldb/lldb-private.h"
class CommunicationKDP : public lldb_private::Communication {
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 2e707ab2e363..c1c3678617c0 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -7,20 +7,15 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <stdlib.h>
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
-#include "lldb/Utility/UUID.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
@@ -37,13 +32,14 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StringExtractor.h"
+#include "lldb/Utility/UUID.h"
#include "llvm/Support/Threading.h"
#define USEC_PER_SEC 1000000
-// Project includes
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
#include "ProcessKDP.h"
@@ -55,10 +51,9 @@ using namespace lldb_private;
namespace {
-static PropertyDefinition g_properties[] = {
- {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, NULL,
- "Specify the default packet timeout in seconds."},
- {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+static constexpr PropertyDefinition g_properties[] = {
+ {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {},
+ "Specify the default packet timeout in seconds."}};
enum { ePropertyPacketTimeout };
@@ -301,7 +296,8 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
if (module_spec.GetSymbolFileSpec()) {
ModuleSpec executable_module_spec =
Symbols::LocateExecutableObjectFile(module_spec);
- if (executable_module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(
+ executable_module_spec.GetFileSpec())) {
module_spec.GetFileSpec() =
executable_module_spec.GetFileSpec();
}
@@ -310,7 +306,7 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
!module_spec.GetSymbolFileSpec())
Symbols::DownloadObjectAndSymbolFile(module_spec, true);
- if (module_spec.GetFileSpec().Exists()) {
+ if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
ModuleSP module_sp(new Module(module_spec));
if (module_sp.get() && module_sp->GetObjectFile()) {
// Get the current target executable
@@ -319,7 +315,7 @@ Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
// Make sure you don't already have the right module loaded
// and they will be uniqued
if (exe_module_sp.get() != module_sp.get())
- target.SetExecutableModule(module_sp, false);
+ target.SetExecutableModule(module_sp, eLoadDependentsNo);
}
}
}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index b4eae58af83c..f9102442de93 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -10,19 +10,16 @@
#ifndef liblldb_ProcessKDP_h_
#define liblldb_ProcessKDP_h_
-// C Includes
-// C++ Includes
#include <list>
#include <vector>
-// Other libraries and framework includes
-#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/Broadcaster.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
index 159a046b617d..0f9e62ce355a 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
@@ -9,10 +9,6 @@
#include "RegisterContextKDP_arm.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "ProcessKDP.h"
#include "ThreadKDP.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
index fe02b0648221..1532f23207f4 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
@@ -10,11 +10,7 @@
#ifndef liblldb_RegisterContextKDP_arm_h_
#define liblldb_RegisterContextKDP_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
class ThreadKDP;
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
index 44534a252568..e13a7f3ad907 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
@@ -10,10 +10,6 @@
#include "RegisterContextKDP_arm64.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "ProcessKDP.h"
#include "ThreadKDP.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
index 0922654de2cc..be4038ba96ea 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
@@ -11,11 +11,7 @@
#ifndef liblldb_RegisterContextKDP_arm64_h_
#define liblldb_RegisterContextKDP_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
class ThreadKDP;
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
index e48232ad8dda..096aa0f95d00 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextKDP_i386.h"
#include "ProcessKDP.h"
#include "ThreadKDP.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
index 5803670a08b4..699d5fabe157 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextKDP_i386_h_
#define liblldb_RegisterContextKDP_i386_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
class ThreadKDP;
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
index 50e11f381925..9d85145f2eaf 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextKDP_x86_64.h"
#include "ProcessKDP.h"
#include "ThreadKDP.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
index 7a40bb626385..9841ad77b004 100644
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
+++ b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextKDP_x86_64_h_
#define liblldb_RegisterContextKDP_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
class ThreadKDP;
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index 7fca0fc24fdb..6f26acd0b8aa 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -9,10 +9,9 @@
#include "ThreadKDP.h"
-#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
@@ -20,6 +19,7 @@
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt
index 92a6014ced07..e131e6d70468 100644
--- a/source/Plugins/Process/NetBSD/CMakeLists.txt
+++ b/source/Plugins/Process/NetBSD/CMakeLists.txt
@@ -5,7 +5,6 @@ add_lldb_library(lldbPluginProcessNetBSD PLUGIN
NativeThreadNetBSD.cpp
LINK_LIBS
- lldbCore
lldbHost
lldbSymbol
lldbTarget
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 1a4cb21d000e..a1b7d7df4553 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -9,18 +9,14 @@
#include "NativeProcessNetBSD.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/State.h"
#include "llvm/Support/Errno.h"
// System includes - They have to be included after framework includes because
@@ -322,100 +318,6 @@ Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
return error;
}
-Status NativeProcessNetBSD::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};
- switch (m_arch.GetMachine()) {
- case llvm::Triple::x86_64:
- actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode));
- return Status();
- default:
- assert(false && "CPU type not supported!");
- return Status("CPU type not supported");
- }
-}
-
-Status
-NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- Status error;
- // Find out the size of a breakpoint (might depend on where we are in the
- // code).
- NativeRegisterContext& context = thread.GetRegisterContext();
- uint32_t breakpoint_size = 0;
- error = GetSoftwareBreakpointPCOffset(breakpoint_size);
- if (error.Fail()) {
- LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error);
- return error;
- } else
- LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
- // First try probing for a breakpoint at a software breakpoint location: PC -
- // breakpoint size.
- 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.
- if (breakpoint_addr >= breakpoint_size)
- breakpoint_addr -= breakpoint_size;
- }
- // Check if we stopped because of a breakpoint.
- NativeBreakpointSP breakpoint_sp;
- error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
- if (!error.Success() || !breakpoint_sp) {
- // We didn't find one at a software probe location. Nothing to do.
- LLDB_LOG(log,
- "pid {0} no lldb breakpoint found at current pc with "
- "adjustment: {1}",
- GetID(), breakpoint_addr);
- return Status();
- }
- // If the breakpoint is not a software breakpoint, nothing to do.
- if (!breakpoint_sp->IsSoftwareBreakpoint()) {
- LLDB_LOG(
- log,
- "pid {0} breakpoint found at {1:x}, not software, nothing to adjust",
- GetID(), breakpoint_addr);
- return Status();
- }
- //
- // We have a software breakpoint and need to adjust the PC.
- //
- // Sanity check.
- if (breakpoint_size == 0) {
- // Nothing to do! How did we get here?
- LLDB_LOG(log,
- "pid {0} breakpoint found at {1:x}, it is software, but the "
- "size is zero, nothing to do (unexpected)",
- GetID(), breakpoint_addr);
- return Status();
- }
- //
- // We have a software breakpoint and need to adjust the PC.
- //
- // Sanity check.
- if (breakpoint_size == 0) {
- // Nothing to do! How did we get here?
- LLDB_LOG(log,
- "pid {0} breakpoint found at {1:x}, it is software, but the "
- "size is zero, nothing to do (unexpected)",
- GetID(), breakpoint_addr);
- return Status();
- }
- // 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.SetPC(breakpoint_addr);
- if (error.Fail()) {
- LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
- thread.GetID(), error);
- return error;
- }
- return error;
-}
-
Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid {0}", GetID());
@@ -637,7 +539,7 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
info.SetName(vm[i].kve_path);
m_mem_region_cache.emplace_back(
- info, FileSpec(info.GetName().GetCString(), true));
+ info, FileSpec(info.GetName().GetCString()));
}
free(vm);
@@ -682,23 +584,6 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
return SetSoftwareBreakpoint(addr, size);
}
-Status NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode(
- size_t trap_opcode_size_hint, size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) {
- static const uint8_t g_i386_opcode[] = {0xCC};
-
- switch (m_arch.GetMachine()) {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- trap_opcode_bytes = g_i386_opcode;
- actual_opcode_size = sizeof(g_i386_opcode);
- return Status();
- default:
- assert(false && "CPU type not supported!");
- return Status("CPU type not supported");
- }
-}
-
Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
FileSpec &file_spec) {
return Status("Unimplemented");
@@ -824,15 +709,6 @@ Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf,
return Status();
}
-Status NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
- size_t size,
- size_t &bytes_read) {
- Status error = ReadMemory(addr, buf, size, bytes_read);
- if (error.Fail())
- return error;
- return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
-}
-
Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
size_t size, size_t &bytes_written) {
const unsigned char *src = static_cast<const unsigned char *>(buf);
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 142f74ecf194..a3f1c4c6a06a 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -58,9 +58,6 @@ public:
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
size_t &bytes_read) override;
- Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
size_t &bytes_written) override;
@@ -93,16 +90,6 @@ public:
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
int data = 0, int *result = nullptr);
-protected:
- // ---------------------------------------------------------------------
- // NativeProcessProtocol protected interface
- // ---------------------------------------------------------------------
-
- Status
- GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
- size_t &actual_opcode_size,
- const uint8_t *&trap_opcode_bytes) override;
-
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
@@ -125,8 +112,6 @@ private:
void MonitorSIGTRAP(lldb::pid_t pid);
void MonitorSignal(lldb::pid_t pid, int signal);
- Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
- Status FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread);
Status PopulateMemoryRegionCache();
void SigchldHandler();
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 16b6f2c52dd5..78da3527122f 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -11,10 +11,10 @@
#include "NativeRegisterContextNetBSD_x86_64.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 83f1da78d01d..6f5d1120e40d 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -14,9 +14,9 @@
#include "Plugins/Process/POSIX/CrashReason.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/State.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
#include <sstream>
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
index 134013517a11..3ac798b3d4b3 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
+++ b/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
@@ -11,11 +11,7 @@
#ifndef liblldb_ProcessPOSIXLog_h_
#define liblldb_ProcessPOSIXLog_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/Log.h"
#define POSIX_LOG_PROCESS (1u << 1)
diff --git a/source/Plugins/Process/Utility/ARMUtils.h b/source/Plugins/Process/Utility/ARMUtils.h
index 2bbd519b246a..2c14dc936cbc 100644
--- a/source/Plugins/Process/Utility/ARMUtils.h
+++ b/source/Plugins/Process/Utility/ARMUtils.h
@@ -12,7 +12,7 @@
#include "ARMDefines.h"
#include "InstructionUtils.h"
-#include "llvm/Support/MathExtras.h" // for SignExtend64 template function
+#include "llvm/Support/MathExtras.h"
// Common utilities for the ARM/Thumb Instruction Set Architecture.
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index b43756acea63..e36ce4dec98a 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -5,6 +5,7 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN
HistoryThread.cpp
HistoryUnwind.cpp
InferiorCallPOSIX.cpp
+ LinuxProcMaps.cpp
LinuxSignals.cpp
MipsLinuxSignals.cpp
NativeRegisterContextRegisterInfo.cpp
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 5f34e9915ede..dcbf474fa55a 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -464,7 +464,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
end = m_value_regs_map.end();
pos != end; ++pos) {
if (pos->second.size() > 1) {
- std::sort(pos->second.begin(), pos->second.end());
+ llvm::sort(pos->second.begin(), pos->second.end());
reg_num_collection::iterator unique_end =
std::unique(pos->second.begin(), pos->second.end());
if (unique_end != pos->second.end())
@@ -514,7 +514,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) {
end = m_invalidate_regs_map.end();
pos != end; ++pos) {
if (pos->second.size() > 1) {
- std::sort(pos->second.begin(), pos->second.end());
+ llvm::sort(pos->second.begin(), pos->second.end());
reg_num_collection::iterator unique_end =
std::unique(pos->second.begin(), pos->second.end());
if (unique_end != pos->second.end())
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
index acb3e3eb8a84..68f3902e0c96 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -10,13 +10,9 @@
#ifndef lldb_DynamicRegisterInfo_h_
#define lldb_DynamicRegisterInfo_h_
-// C Includes
-// C++ Includes
#include <map>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
index f695a11c9759..0b56b6093559 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "FreeBSDSignals.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h
index 8ec96e824f7a..174025cabb82 100644
--- a/source/Plugins/Process/Utility/FreeBSDSignals.h
+++ b/source/Plugins/Process/Utility/FreeBSDSignals.h
@@ -10,7 +10,6 @@
#ifndef liblldb_FreeBSDSignals_H_
#define liblldb_FreeBSDSignals_H_
-// Project includes
#include "lldb/Target/UnixSignals.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
index abcc8a38669a..cc0537c2a8b3 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "GDBRemoteSignals.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h
index 5900fa75d6f2..79d8ec3fbbaf 100644
--- a/source/Plugins/Process/Utility/GDBRemoteSignals.h
+++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h
@@ -10,10 +10,6 @@
#ifndef liblldb_GDBRemoteSignals_H_
#define liblldb_GDBRemoteSignals_H_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/UnixSignals.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
index 7675a95246a7..dc24922e7c17 100644
--- a/source/Plugins/Process/Utility/HistoryThread.h
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -10,18 +10,14 @@
#ifndef liblldb_HistoryThread_h_
#define liblldb_HistoryThread_h_
-// C Includes
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/Broadcaster.h"
-#include "lldb/Core/Event.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/Event.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
index 3b64e38bfaa7..2cbfb680ef49 100644
--- a/source/Plugins/Process/Utility/HistoryUnwind.h
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -10,12 +10,8 @@
#ifndef liblldb_HistoryUnwind_h_
#define liblldb_HistoryUnwind_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Unwind.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/source/Plugins/Process/Utility/LinuxProcMaps.cpp
new file mode 100644
index 000000000000..d45bf6dcd84f
--- /dev/null
+++ b/source/Plugins/Process/Utility/LinuxProcMaps.cpp
@@ -0,0 +1,113 @@
+//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LinuxProcMaps.h"
+#include "llvm/ADT/StringRef.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StringExtractor.h"
+
+using namespace lldb_private;
+
+static Status
+ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line,
+ MemoryRegionInfo &memory_region_info) {
+ memory_region_info.Clear();
+
+ StringExtractor line_extractor(maps_line);
+
+ // Format: {address_start_hex}-{address_end_hex} perms offset dev inode
+ // pathname perms: rwxp (letter is present if set, '-' if not, final
+ // character is p=private, s=shared).
+
+ // Parse out the starting address
+ lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0);
+
+ // Parse out hyphen separating start and end address from range.
+ if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-'))
+ return Status(
+ "malformed /proc/{pid}/maps entry, missing dash between address range");
+
+ // Parse out the ending address
+ lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address);
+
+ // Parse out the space after the address.
+ if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' '))
+ return Status(
+ "malformed /proc/{pid}/maps entry, missing space after range");
+
+ // Save the range.
+ memory_region_info.GetRange().SetRangeBase(start_address);
+ memory_region_info.GetRange().SetRangeEnd(end_address);
+
+ // Any memory region in /proc/{pid}/maps is by definition mapped into the
+ // process.
+ memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
+
+ // Parse out each permission entry.
+ if (line_extractor.GetBytesLeft() < 4)
+ return Status("malformed /proc/{pid}/maps entry, missing some portion of "
+ "permissions");
+
+ // Handle read permission.
+ const char read_perm_char = line_extractor.GetChar();
+ if (read_perm_char == 'r')
+ memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (read_perm_char == '-')
+ memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Status("unexpected /proc/{pid}/maps read permission char");
+
+ // Handle write permission.
+ const char write_perm_char = line_extractor.GetChar();
+ if (write_perm_char == 'w')
+ memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (write_perm_char == '-')
+ memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Status("unexpected /proc/{pid}/maps write permission char");
+
+ // Handle execute permission.
+ const char exec_perm_char = line_extractor.GetChar();
+ if (exec_perm_char == 'x')
+ memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
+ else if (exec_perm_char == '-')
+ memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
+ else
+ return Status("unexpected /proc/{pid}/maps exec permission char");
+
+ line_extractor.GetChar(); // Read the private bit
+ line_extractor.SkipSpaces(); // Skip the separator
+ line_extractor.GetHexMaxU64(false, 0); // Read the offset
+ line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+ line_extractor.GetChar(); // Read the device id separator
+ line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+ line_extractor.SkipSpaces(); // Skip the separator
+ line_extractor.GetU64(0, 10); // Read the inode number
+
+ line_extractor.SkipSpaces();
+ const char *name = line_extractor.Peek();
+ if (name)
+ memory_region_info.SetName(name);
+
+ return Status();
+}
+
+void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map,
+ LinuxMapCallback const &callback) {
+ llvm::StringRef lines(linux_map);
+ llvm::StringRef line;
+ while (!lines.empty()) {
+ std::tie(line, lines) = lines.split('\n');
+ MemoryRegionInfo region;
+ Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region);
+ if (!callback(region, error))
+ break;
+ }
+}
diff --git a/source/Plugins/Process/Utility/LinuxProcMaps.h b/source/Plugins/Process/Utility/LinuxProcMaps.h
new file mode 100644
index 000000000000..e6eabb28fc82
--- /dev/null
+++ b/source/Plugins/Process/Utility/LinuxProcMaps.h
@@ -0,0 +1,28 @@
+//===-- LinuxProcMaps.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_LinuxProcMaps_H_
+#define liblldb_LinuxProcMaps_H_
+
+#include "lldb/lldb-forward.h"
+#include "llvm/ADT/StringRef.h"
+#include <functional>
+
+
+namespace lldb_private {
+
+typedef std::function<bool(const lldb_private::MemoryRegionInfo &,
+ const lldb_private::Status &)> LinuxMapCallback;
+
+void ParseLinuxMapRegions(llvm::StringRef linux_map,
+ LinuxMapCallback const &callback);
+
+} // namespace lldb_private
+
+#endif // liblldb_LinuxProcMaps_H_
diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp
index eb01075ed133..6f1f67ac3570 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/LinuxSignals.cpp
@@ -7,9 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "LinuxSignals.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h
index e41126225cee..f93a9d2e36d1 100644
--- a/source/Plugins/Process/Utility/LinuxSignals.h
+++ b/source/Plugins/Process/Utility/LinuxSignals.h
@@ -10,10 +10,6 @@
#ifndef liblldb_LinuxSignals_H_
#define liblldb_LinuxSignals_H_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/UnixSignals.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
index 36231023aa3a..b6f3b34893bf 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp
@@ -8,9 +8,6 @@
//
//===----------------------------------------------------------------------===//
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "MipsLinuxSignals.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h
index e48ea5943f2b..2796f6b8e4d7 100644
--- a/source/Plugins/Process/Utility/MipsLinuxSignals.h
+++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h
@@ -11,10 +11,6 @@
#ifndef liblldb_MipsLinuxSignals_H_
#define liblldb_MipsLinuxSignals_H_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/UnixSignals.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.cpp b/source/Plugins/Process/Utility/NetBSDSignals.cpp
index 7ed7189d8048..a4baab9ac85f 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.cpp
+++ b/source/Plugins/Process/Utility/NetBSDSignals.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "NetBSDSignals.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/NetBSDSignals.h b/source/Plugins/Process/Utility/NetBSDSignals.h
index 4338f881645e..7bb57fa0c0d6 100644
--- a/source/Plugins/Process/Utility/NetBSDSignals.h
+++ b/source/Plugins/Process/Utility/NetBSDSignals.h
@@ -10,7 +10,6 @@
#ifndef liblldb_NetBSDSignals_H_
#define liblldb_NetBSDSignals_H_
-// Project includes
#include "lldb/Target/UnixSignals.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
index 5d9ff02fafdd..9ad896abd0b4 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
@@ -10,14 +10,12 @@
#include "RegisterContextDarwin_arm.h"
#include "RegisterContextDarwinConstants.h"
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
@@ -28,7 +26,6 @@
#define LLVM_EXTENSION
#endif
-// Project includes
#include "Utility/ARM_DWARF_Registers.h"
#include "Utility/ARM_ehframe_Registers.h"
@@ -1673,7 +1670,7 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
return LLDB_INVALID_INDEX32;
// We must watch for either read or write
- if (read == false && write == false)
+ if (!read && !write)
return LLDB_INVALID_INDEX32;
// Can't watch more than 4 bytes per WVR/WCR pair
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
index cdf3479dff69..b46946d608bc 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextDarwin_arm_h_
#define liblldb_RegisterContextDarwin_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 03ce7ef9f524..b478645e035d 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -11,16 +11,14 @@
#include "RegisterContextDarwin_arm64.h"
#include "RegisterContextDarwinConstants.h"
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
@@ -32,7 +30,6 @@
#define LLVM_EXTENSION
#endif
-// Project includes
#include "Utility/ARM64_DWARF_Registers.h"
using namespace lldb;
@@ -341,12 +338,22 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case gpr_x26:
case gpr_x27:
case gpr_x28:
+ value.SetUInt64(gpr.x[reg - gpr_x0]);
+ break;
case gpr_fp:
+ value.SetUInt64(gpr.fp);
+ break;
case gpr_sp:
+ value.SetUInt64(gpr.sp);
+ break;
case gpr_lr:
+ value.SetUInt64(gpr.lr);
+ break;
case gpr_pc:
+ value.SetUInt64(gpr.pc);
+ break;
case gpr_cpsr:
- value.SetUInt64(gpr.x[reg - gpr_x0]);
+ value.SetUInt64(gpr.cpsr);
break;
case gpr_w0:
@@ -949,7 +956,7 @@ uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr,
return LLDB_INVALID_INDEX32;
// We must watch for either read or write
- if (read == false && write == false)
+ if (!read && !write)
return LLDB_INVALID_INDEX32;
// Can't watch more than 4 bytes per WVR/WCR pair
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index 4a0e50947ee7..9e826d85af08 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -11,10 +11,6 @@
#ifndef liblldb_RegisterContextDarwin_arm64_h_
#define liblldb_RegisterContextDarwin_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
index 24414211d9aa..c9e4b37a17f3 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
@@ -7,17 +7,14 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <stddef.h> // offsetof
+#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
@@ -27,7 +24,6 @@
#define LLVM_EXTENSION
#endif
-// Project includes
#include "RegisterContextDarwin_i386.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
index aea8a2900911..ad6a1e48fc34 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextDarwin_i386_h_
#define liblldb_RegisterContextDarwin_i386_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
index ecad8240b294..95460308857a 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
@@ -7,19 +7,16 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-#include <inttypes.h> // PRIx64
+#include <inttypes.h>
#include <stdarg.h>
-#include <stddef.h> // offsetof
+#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
@@ -29,7 +26,6 @@
#define LLVM_EXTENSION
#endif
-// Project includes
#include "RegisterContextDarwin_x86_64.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
index fdd5e8036dee..6d94bf75aad4 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextDarwin_x86_64_h_
#define liblldb_RegisterContextDarwin_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
index dd6ca92a74ee..c51c30f45a5d 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.cpp
@@ -11,7 +11,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/FuncUnwinders.h"
@@ -28,6 +27,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/lldb-private.h"
#include "RegisterContextDummy.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextDummy.h b/source/Plugins/Process/Utility/RegisterContextDummy.h
index ea70288f3d69..d5608616c896 100644
--- a/source/Plugins/Process/Utility/RegisterContextDummy.h
+++ b/source/Plugins/Process/Utility/RegisterContextDummy.h
@@ -11,12 +11,8 @@
#ifndef lldb_RegisterContextDummy_h_
#define lldb_RegisterContextDummy_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
index c9a65b1cacce..b74d0ea75469 100644
--- a/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h
@@ -11,10 +11,6 @@
#ifndef liblldb_RegisterContextFreeBSD_powerpc_h_
#define liblldb_RegisterContextFreeBSD_powerpc_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterInfoInterface.h"
class RegisterContextFreeBSD_powerpc
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
index cc0d696b338a..c9b77663a803 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
@@ -11,7 +11,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/FuncUnwinders.h"
@@ -28,6 +27,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/lldb-private.h"
#include "RegisterContextHistory.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.h b/source/Plugins/Process/Utility/RegisterContextHistory.h
index acaf8fe5c04a..01b3624f8c5b 100644
--- a/source/Plugins/Process/Utility/RegisterContextHistory.h
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.h
@@ -11,12 +11,8 @@
#ifndef lldb_RegisterContextHistory_h_
#define lldb_RegisterContextHistory_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index ba9a8071bcfb..8c420a87e1b0 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -10,7 +10,6 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
@@ -31,6 +30,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/lldb-private.h"
#include "RegisterContextLLDB.h"
@@ -54,7 +54,8 @@ RegisterContextLLDB::RegisterContextLLDB(Thread &thread,
: RegisterContext(thread, frame_number), m_thread(thread),
m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(),
m_fallback_unwind_plan_sp(), m_all_registers_available(false),
- m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), m_start_pc(),
+ m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS),
+ m_afa(LLDB_INVALID_ADDRESS), m_start_pc(),
m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0),
m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number),
m_registers(), m_parent_unwind(unwind_lldb) {
@@ -150,7 +151,8 @@ void RegisterContextLLDB::InitializeZerothFrame() {
// We require either a symbol or function in the symbols context to be
// successfully filled in or this context is of no use to us.
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ const SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress(
m_current_pc, resolve_scope, m_sym_ctx) &
resolve_scope)) {
@@ -227,7 +229,7 @@ void RegisterContextLLDB::InitializeZerothFrame() {
return;
}
- if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
// Try the fall back unwind plan since the
// full unwind plan failed.
FuncUnwindersSP func_unwinders_sp;
@@ -255,12 +257,14 @@ void RegisterContextLLDB::InitializeZerothFrame() {
m_frame_type = eNotAValidFrame;
return;
}
- }
+ } else
+ ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64
- " using %s UnwindPlan",
+ " afa is 0x%" PRIx64 " using %s UnwindPlan",
(uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
(uint64_t)m_cfa,
+ (uint64_t)m_afa,
m_full_unwind_plan_sp->GetSourceName().GetCString());
}
@@ -320,7 +324,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
above_trap_handler = true;
if (pc == 0 || pc == 0x1) {
- if (above_trap_handler == false) {
+ if (!above_trap_handler) {
m_frame_type = eNotAValidFrame;
UnwindLogMsg("this frame has a pc of 0x0");
return;
@@ -378,7 +382,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
if (row.get()) {
- if (!ReadCFAValueForRow(row_register_kind, row, m_cfa)) {
+ if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) {
UnwindLogMsg("failed to get cfa value");
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
@@ -387,6 +391,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
return;
}
+ ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa);
+
// A couple of sanity checks..
if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) {
UnwindLogMsg("could not find a valid cfa address");
@@ -419,7 +425,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
}
}
- UnwindLogMsg("initialized frame cfa is 0x%" PRIx64, (uint64_t)m_cfa);
+ UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
+ (uint64_t)m_cfa, (uint64_t)m_afa);
return;
}
m_frame_type = eNotAValidFrame;
@@ -436,7 +443,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
// then we might not find the correct unwind information later. Instead, let
// ResolveSymbolContextForAddress fail, and handle the case via
// decr_pc_and_recompute_addr_range below.
- const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ const SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress(
m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address);
@@ -466,7 +474,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
bool decr_pc_and_recompute_addr_range = false;
// If the symbol lookup failed...
- if (m_sym_ctx_valid == false)
+ if (!m_sym_ctx_valid)
decr_pc_and_recompute_addr_range = true;
// Or if we're in the middle of the stack (and not "above" an asynchronous
@@ -494,7 +502,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
- uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ SymbolContextItem resolve_scope =
+ eSymbolContextFunction | eSymbolContextSymbol;
ModuleSP temporary_module_sp = temporary_pc.GetModule();
if (temporary_module_sp &&
@@ -581,13 +590,15 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
return;
}
- if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) {
+ if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
UnwindLogMsg("failed to get cfa");
m_frame_type = eNotAValidFrame;
return;
}
- UnwindLogMsg("m_cfa = 0x%" PRIx64, m_cfa);
+ ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);
+
+ UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa);
if (CheckIfLoopingStack()) {
TryFallbackUnwindPlan();
@@ -600,9 +611,10 @@ void RegisterContextLLDB::InitializeNonZerothFrame() {
}
UnwindLogMsg("initialized frame current pc is 0x%" PRIx64
- " cfa is 0x%" PRIx64,
+ " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64,
(uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()),
- (uint64_t)m_cfa);
+ (uint64_t)m_cfa,
+ (uint64_t)m_afa);
}
bool RegisterContextLLDB::CheckIfLoopingStack() {
@@ -1238,7 +1250,7 @@ RegisterContextLLDB::SavedLocationForRegister(
// Address register and it hasn't been saved anywhere yet -- that is,
// it's still live in the actual register. Handle this specially.
- if (have_unwindplan_regloc == false && return_address_reg.IsValid() &&
+ if (!have_unwindplan_regloc && return_address_reg.IsValid() &&
IsFrameZero()) {
if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
LLDB_INVALID_REGNUM) {
@@ -1311,17 +1323,13 @@ RegisterContextLLDB::SavedLocationForRegister(
unwindplan_regloc)) {
can_fetch_pc_value = true;
}
- if (ReadCFAValueForRow(unwindplan_registerkind, active_row,
- cfa_value)) {
+ if (ReadFrameAddress(unwindplan_registerkind,
+ active_row->GetCFAValue(), cfa_value)) {
can_fetch_cfa = true;
}
}
- if (can_fetch_pc_value && can_fetch_cfa) {
- have_unwindplan_regloc = true;
- } else {
- have_unwindplan_regloc = false;
- }
+ have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa;
} else {
// We were unable to fall back to another unwind plan
have_unwindplan_regloc = false;
@@ -1332,7 +1340,7 @@ RegisterContextLLDB::SavedLocationForRegister(
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
- if (have_unwindplan_regloc == false) {
+ if (!have_unwindplan_regloc) {
// If the UnwindPlan failed to give us an unwind location for this
// register, we may be able to fall back to some ABI-defined default. For
// example, some ABIs allow to determine the caller's SP via the CFA. Also,
@@ -1351,7 +1359,7 @@ RegisterContextLLDB::SavedLocationForRegister(
}
}
- if (have_unwindplan_regloc == false) {
+ if (!have_unwindplan_regloc) {
if (IsFrameZero()) {
// This is frame 0 - we should return the actual live register context
// value
@@ -1397,7 +1405,7 @@ RegisterContextLLDB::SavedLocationForRegister(
}
if (unwindplan_regloc.IsSame()) {
- if (IsFrameZero() == false &&
+ if (!IsFrameZero() &&
(regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC ||
regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) {
UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or "
@@ -1441,6 +1449,36 @@ RegisterContextLLDB::SavedLocationForRegister(
return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
+ if (unwindplan_regloc.IsAFAPlusOffset()) {
+ if (m_afa == LLDB_INVALID_ADDRESS)
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
+ regloc.location.inferred_value = m_afa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus "
+ "offset %d [value is 0x%" PRIx64 "]",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
+ regloc.location.inferred_value);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
+ if (unwindplan_regloc.IsAtAFAPlusOffset()) {
+ if (m_afa == LLDB_INVALID_ADDRESS)
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+
+ int offset = unwindplan_regloc.GetOffset();
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = m_afa + offset;
+ m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
+ UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at "
+ "AFA plus offset %d [saved at 0x%" PRIx64 "]",
+ regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
+ regloc.location.target_memory_location);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+
if (unwindplan_regloc.IsInOtherRegister()) {
uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
RegisterNumber row_regnum(m_thread, unwindplan_registerkind,
@@ -1555,7 +1593,6 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
- addr_t old_this_frame_cfa_value = m_cfa;
UnwindLLDB::RegisterLocation regloc;
if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
regloc) ==
@@ -1585,6 +1622,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
// the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'.
UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
addr_t old_cfa = m_cfa;
+ addr_t old_afa = m_afa;
m_registers.clear();
@@ -1595,19 +1633,21 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
if (active_row &&
active_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::CFAValue::unspecified) {
+ UnwindPlan::Row::FAValue::unspecified) {
addr_t new_cfa;
- if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row, new_cfa) ||
+ if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row->GetCFAValue(), new_cfa) ||
new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
UnwindLogMsg("failed to get cfa with fallback unwindplan");
m_fallback_unwind_plan_sp.reset();
m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
return false;
}
m_cfa = new_cfa;
+ ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row->GetAFAValue(), m_afa);
+
if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
regloc) ==
UnwindLLDB::RegisterSearchResult::eRegisterFound) {
@@ -1628,19 +1668,18 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() {
m_fallback_unwind_plan_sp.reset();
m_full_unwind_plan_sp = original_full_unwind_plan_sp;
m_cfa = old_cfa;
+ m_afa = old_afa;
return false;
}
- if (old_caller_pc_value != LLDB_INVALID_ADDRESS) {
- if (old_caller_pc_value == new_caller_pc_value &&
- new_cfa == old_this_frame_cfa_value) {
- UnwindLogMsg("fallback unwind plan got the same values for this frame "
- "CFA and caller frame pc, not using");
- m_fallback_unwind_plan_sp.reset();
- m_full_unwind_plan_sp = original_full_unwind_plan_sp;
- m_cfa = old_cfa;
- return false;
- }
+ if (old_caller_pc_value == new_caller_pc_value &&
+ m_cfa == old_cfa &&
+ m_afa == old_afa) {
+ UnwindLogMsg("fallback unwind plan got the same values for this frame "
+ "CFA and caller frame pc, not using");
+ m_fallback_unwind_plan_sp.reset();
+ m_full_unwind_plan_sp = original_full_unwind_plan_sp;
+ return false;
}
UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' "
@@ -1674,16 +1713,19 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
if (active_row &&
active_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::CFAValue::unspecified) {
+ UnwindPlan::Row::FAValue::unspecified) {
addr_t new_cfa;
- if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(),
- active_row, new_cfa) ||
+ if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row->GetCFAValue(), new_cfa) ||
new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) {
UnwindLogMsg("failed to get cfa with fallback unwindplan");
m_fallback_unwind_plan_sp.reset();
return false;
}
+ ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
+ active_row->GetAFAValue(), m_afa);
+
m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
m_fallback_unwind_plan_sp.reset();
@@ -1698,18 +1740,18 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() {
return false;
}
-bool RegisterContextLLDB::ReadCFAValueForRow(
- lldb::RegisterKind row_register_kind, const UnwindPlan::RowSP &row,
- addr_t &cfa_value) {
+bool RegisterContextLLDB::ReadFrameAddress(
+ lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa,
+ addr_t &address) {
RegisterValue reg_value;
- cfa_value = LLDB_INVALID_ADDRESS;
+ address = LLDB_INVALID_ADDRESS;
addr_t cfa_reg_contents;
- switch (row->GetCFAValue().GetValueType()) {
- case UnwindPlan::Row::CFAValue::isRegisterDereferenced: {
+ switch (fa.GetValueType()) {
+ case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
RegisterNumber cfa_reg(m_thread, row_register_kind,
- row->GetCFAValue().GetRegisterNumber());
+ fa.GetRegisterNumber());
if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
const RegisterInfo *reg_info =
GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB));
@@ -1718,12 +1760,12 @@ bool RegisterContextLLDB::ReadCFAValueForRow(
Status error = ReadRegisterValueFromMemory(
reg_info, cfa_reg_contents, reg_info->byte_size, reg_value);
if (error.Success()) {
- cfa_value = reg_value.GetAsUInt64();
+ address = reg_value.GetAsUInt64();
UnwindLogMsg(
"CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64
", CFA value is 0x%" PRIx64,
cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents, cfa_value);
+ cfa_reg_contents, address);
return true;
} else {
UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64
@@ -1735,9 +1777,9 @@ bool RegisterContextLLDB::ReadCFAValueForRow(
}
break;
}
- case UnwindPlan::Row::CFAValue::isRegisterPlusOffset: {
+ case UnwindPlan::Row::FAValue::isRegisterPlusOffset: {
RegisterNumber cfa_reg(m_thread, row_register_kind,
- row->GetCFAValue().GetRegisterNumber());
+ fa.GetRegisterNumber());
if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 ||
cfa_reg_contents == 1) {
@@ -1748,35 +1790,35 @@ bool RegisterContextLLDB::ReadCFAValueForRow(
cfa_reg_contents = LLDB_INVALID_ADDRESS;
return false;
}
- cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset();
+ address = cfa_reg_contents + fa.GetOffset();
UnwindLogMsg(
"CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64
", offset is %d",
- cfa_value, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
- cfa_reg_contents, row->GetCFAValue().GetOffset());
+ address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
+ cfa_reg_contents, fa.GetOffset());
return true;
}
break;
}
- case UnwindPlan::Row::CFAValue::isDWARFExpression: {
+ case UnwindPlan::Row::FAValue::isDWARFExpression: {
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
- DataExtractor dwarfdata(row->GetCFAValue().GetDWARFExpressionBytes(),
- row->GetCFAValue().GetDWARFExpressionLength(),
+ DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(),
+ fa.GetDWARFExpressionLength(),
process->GetByteOrder(),
process->GetAddressByteSize());
ModuleSP opcode_ctx;
DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0,
- row->GetCFAValue().GetDWARFExpressionLength());
+ fa.GetDWARFExpressionLength());
dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
&error)) {
- cfa_value = result.GetScalar().ULongLong();
+ address = result.GetScalar().ULongLong();
UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
- cfa_value);
+ address);
return true;
}
UnwindLogMsg("Failed to set CFA value via DWARF expression: %s",
@@ -2005,12 +2047,8 @@ bool RegisterContextLLDB::ReadPC(addr_t &pc) {
pc = abi->FixCodeAddress(pc);
}
- if (m_all_registers_available == false && above_trap_handler == false &&
- (pc == 0 || pc == 1)) {
- return false;
- }
-
- return true;
+ return !(m_all_registers_available == false &&
+ above_trap_handler == false && (pc == 0 || pc == 1));
} else {
return false;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.h b/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 7e9e77dcf06d..50f12c6f8541 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -11,12 +11,8 @@
#ifndef lldb_RegisterContextLLDB_h_
#define lldb_RegisterContextLLDB_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "UnwindLLDB.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/UnwindPlan.h"
@@ -192,9 +188,9 @@ private:
bool ReadGPRValue(const RegisterNumber &reg_num, lldb::addr_t &value);
- // Get the CFA register for a given frame.
- bool ReadCFAValueForRow(lldb::RegisterKind register_kind,
- const UnwindPlan::RowSP &row, lldb::addr_t &value);
+ // Get the Frame Address register for a given frame.
+ bool ReadFrameAddress(lldb::RegisterKind register_kind,
+ UnwindPlan::Row::FAValue &fa, lldb::addr_t &address);
lldb::UnwindPlanSP GetFastUnwindPlanForFrame();
@@ -225,6 +221,7 @@ private:
int m_frame_type; // enum FrameType
lldb::addr_t m_cfa;
+ lldb::addr_t m_afa;
lldb_private::Address m_start_pc;
lldb_private::Address m_current_pc;
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
index 77c1bea34851..c0a6084cd723 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
@@ -9,16 +9,12 @@
#include "RegisterContextMacOSXFrameBackchain.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
-// Project includes
#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
index 4f5816aa4909..69e23c2782fd 100644
--- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
@@ -10,10 +10,6 @@
#ifndef lldb_RegisterContextMacOSXFrameBackchain_h_
#define lldb_RegisterContextMacOSXFrameBackchain_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index 71d35bbd3938..69522ace1a68 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -11,13 +11,9 @@
#include "RegisterContextMach_arm.h"
-// C Includes
#include <mach/mach_types.h>
#include <mach/thread_act.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
index a2cf6bfcbe4a..5ea47f214e25 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.h
@@ -10,11 +10,7 @@
#ifndef liblldb_RegisterContextMach_arm_h_
#define liblldb_RegisterContextMach_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextDarwin_arm.h"
class RegisterContextMach_arm : public RegisterContextDarwin_arm {
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index 5a260d5de1d5..94138605239e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -9,12 +9,8 @@
#if defined(__APPLE__)
-// C Includes
#include <mach/thread_act.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextMach_i386.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
index 8ac693a55584..a7e29e96b267 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextMach_i386_h_
#define liblldb_RegisterContextMach_i386_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextDarwin_i386.h"
class RegisterContextMach_i386 : public RegisterContextDarwin_i386 {
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index 0180879d51ee..e523b95ee974 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -9,12 +9,8 @@
#if defined(__APPLE__)
-// C Includes
#include <mach/thread_act.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextMach_x86_64.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
index cd425046b08e..c73bdda79713 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h
@@ -11,10 +11,6 @@
#ifndef liblldb_RegisterContextMach_x86_64_h_
#define liblldb_RegisterContextMach_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContextDarwin_x86_64.h"
class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 {
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
index 76189ea781de..f05c07f6c8e1 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.cpp
@@ -9,15 +9,11 @@
#include "RegisterContextMemory.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "DynamicRegisterInfo.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
using namespace lldb;
diff --git a/source/Plugins/Process/Utility/RegisterContextMemory.h b/source/Plugins/Process/Utility/RegisterContextMemory.h
index cad1592af5ba..cdf2a5446e1e 100644
--- a/source/Plugins/Process/Utility/RegisterContextMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextMemory.h
@@ -10,12 +10,8 @@
#ifndef lldb_RegisterContextMemory_h_
#define lldb_RegisterContextMemory_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
index 352e251e3b64..b0e53cfcc91f 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_arm.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
index 8c5fe9d2c2de..4b5a8fe95a4f 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_arm_h_
#define liblldb_RegisterContextPOSIX_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterInfoInterface.h"
#include "lldb-arm-register-enums.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
index 3ff93cde2347..8b00dfc81eab 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_arm64.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
index 27251da2a9af..603c12d830d9 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_arm64_h_
#define liblldb_RegisterContextPOSIX_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterInfoInterface.h"
#include "lldb-arm64-register-enums.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
index 98d1e6fa8817..9270d09f7293 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_mips64.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
index 1695ec9a0bab..09cfd42b9c51 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_mips64_h_
#define liblldb_RegisterContextPOSIX_mips64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContext_mips.h"
#include "RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
index 9f0552539723..47a8e2c3f9e9 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp
@@ -12,14 +12,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_powerpc.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
index 50f234680ca0..3260cb1ce8bc 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_powerpc_h_
#define liblldb_RegisterContextPOSIX_powerpc_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContext_powerpc.h"
#include "RegisterInfoInterface.h"
#include "lldb/Target/RegisterContext.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
index 41ae5ec6b51a..ef221c963dc4 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_ppc64le.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
index 1070b4dea405..9159819f17c4 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
@@ -10,10 +10,6 @@
#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"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
index 662ac38405ef..24f131099be4 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_s390x.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
index d5337630c32d..7a7b6bddd6aa 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_s390x_h_
#define liblldb_RegisterContextPOSIX_s390x_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContext_s390x.h"
#include "RegisterInfoInterface.h"
#include "lldb-s390x-register-enums.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index d2a06e1b7897..78f561a0f04f 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -11,14 +11,14 @@
#include <errno.h>
#include <stdint.h>
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "llvm/Support/Compiler.h"
#include "RegisterContextPOSIX_x86.h"
@@ -376,7 +376,7 @@ RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() {
if (m_fpr_type == eNotValid) {
// TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
m_fpr_type = eXSAVE; // extended floating-point registers, if available
- if (false == ReadFPR())
+ if (!ReadFPR())
m_fpr_type = eFXSAVE; // assume generic floating-point registers
}
return m_fpr_type;
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index ca71a6f272f8..b6db45e55bbf 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -10,10 +10,6 @@
#ifndef liblldb_RegisterContextPOSIX_x86_h_
#define liblldb_RegisterContextPOSIX_x86_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "RegisterContext_x86.h"
#include "RegisterInfoInterface.h"
#include "lldb-x86-register-enums.h"
diff --git a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
index 3b3b0856a4ca..0d50c73a31a9 100644
--- a/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
+++ b/source/Plugins/Process/Utility/RegisterContextThreadMemory.h
@@ -10,12 +10,8 @@
#ifndef lldb_RegisterContextThreadMemory_h_
#define lldb_RegisterContextThreadMemory_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
index 6146dcaf7e5a..e3ff492d707a 100644
--- a/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -341,7 +341,7 @@ LLVM_PACKED_END
// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
LLVM_PACKED_START
-struct LLVM_ALIGNAS(64) XSAVE {
+struct LLVM_ALIGNAS(16) XSAVE {
FXSAVE i387; // floating point registers typical in i387_fxsave_struct
XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the
// following extensions are usable
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm.h b/source/Plugins/Process/Utility/RegisterInfos_arm.h
index 74d3226c8a52..ec951ea8a391 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm.h
@@ -9,12 +9,8 @@
#ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT
-// C Includes
#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
index b996533791ff..039d98ecdd2d 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_arm64.h
@@ -9,12 +9,8 @@
#ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT
-// C Includes
#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h
index ffdc4d0d116b..f8947876d15f 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -11,7 +11,6 @@
#include <cstddef>
#include <cstdint>
-// Project includes
#ifdef DECLARE_REGISTER_INFOS_I386_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips.h b/source/Plugins/Process/Utility/RegisterInfos_mips.h
index b116b99b3f81..36483c068d26 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips.h
@@ -7,15 +7,11 @@
//
//===---------------------------------------------------------------------===//
-// C Includes
#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Core/dwarf.h"
#include "llvm/Support/Compiler.h"
-// Project includes
#ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
index 3c3912fa6978..0194074f34f2 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_mips64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_mips64.h
@@ -7,15 +7,11 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Core/dwarf.h"
#include "llvm/Support/Compiler.h"
-// Project includes
#ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
index 69f00e4ba885..dbd87ad71a45 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64.h
@@ -9,7 +9,6 @@
#ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT
-// C Includes
#include <stddef.h>
// Computes the offset of the given GPR_PPC64 in the user data area.
diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
index bffa7a1d8b63..e6fa17b60758 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -9,7 +9,6 @@
#ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-// C Includes
#include <stddef.h>
// Computes the offset of the given GPR in the user data area.
diff --git a/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
index 0bbf422405ee..b750be4116a5 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_s390x.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_s390x.h
@@ -7,14 +7,10 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stddef.h>
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Support/Compiler.h"
-// Project includes
#ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 3dbfe611e713..de0821eb4253 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -9,10 +9,12 @@
#include "StopInfoMachException.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+
+#if defined(__APPLE__)
+// Needed for the EXC_RESOURCE interpretation macros
+#include <kern/exc_resource.h>
+#endif
+
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/DynamicLoader.h"
@@ -41,6 +43,12 @@ const char *StopInfoMachException::GetDescription() {
const char *code_desc = NULL;
const char *subcode_label = "subcode";
const char *subcode_desc = NULL;
+
+#if defined(__APPLE__)
+ char code_desc_buf[32];
+ char subcode_desc_buf[32];
+#endif
+
switch (m_value) {
case 1: // EXC_BAD_ACCESS
exc_desc = "EXC_BAD_ACCESS";
@@ -275,6 +283,47 @@ const char *StopInfoMachException::GetDescription() {
break;
case 11:
exc_desc = "EXC_RESOURCE";
+#if defined(__APPLE__)
+ {
+ int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
+
+ code_label = "limit";
+ code_desc = code_desc_buf;
+ subcode_label = "observed";
+ subcode_desc = subcode_desc_buf;
+
+ switch (resource_type) {
+ case RESOURCE_TYPE_CPU:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_WAKEUPS:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
+ (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode));
+ break;
+ case RESOURCE_TYPE_MEMORY:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
+ subcode_desc = nullptr;
+ subcode_label = "unused";
+ break;
+ case RESOURCE_TYPE_IO:
+ exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
+ snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
+ snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
+ (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));;
+ break;
+ }
+ }
+#endif
break;
case 12:
exc_desc = "EXC_GUARD";
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.h b/source/Plugins/Process/Utility/StopInfoMachException.h
index 94516454105e..027ed80e8a98 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.h
+++ b/source/Plugins/Process/Utility/StopInfoMachException.h
@@ -10,12 +10,8 @@
#ifndef liblldb_StopInfoMachException_h_
#define liblldb_StopInfoMachException_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/StopInfo.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/ThreadMemory.h b/source/Plugins/Process/Utility/ThreadMemory.h
index 89229710da4d..c966ca03a017 100644
--- a/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/source/Plugins/Process/Utility/ThreadMemory.h
@@ -10,12 +10,8 @@
#ifndef liblldb_ThreadMemory_h_
#define liblldb_ThreadMemory_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Thread.h"
class ThreadMemory : public lldb_private::Thread {
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 55559f07f1e5..b34c87230bd1 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -130,6 +130,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
+ uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth();
+
// We want to detect an unwind that cycles erroneously and stop backtracing.
// Don't want this maximum unwind limit to be too low -- if you have a
// backtrace with an "infinitely recursing" bug, it will crash when the stack
@@ -138,7 +140,7 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
// unwind at 10,000 or something. Realistically anything over around 200,000
// is going to blow out the stack space. If we're still unwinding at that
// point, we're probably never going to finish.
- if (cur_idx > 300000) {
+ if (cur_idx >= max_stack_depth) {
if (log)
log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
"gone astray, stopping.",
@@ -210,15 +212,15 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
// On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
// have its (constructed) CFA aligned correctly -- don't do the abi
// alignment check for these.
- if (reg_ctx_sp->IsTrapHandlerFrame() == false) {
+ if (!reg_ctx_sp->IsTrapHandlerFrame()) {
// See if we can find a fallback unwind plan for THIS frame. It may be
// that the UnwindPlan we're using for THIS frame was bad and gave us a
// bad CFA. If that's not it, then see if we can change the UnwindPlan
// for the frame below us ("NEXT") -- see if using that other UnwindPlan
// gets us a better unwind state.
- if (reg_ctx_sp->TryFallbackUnwindPlan() == false ||
- reg_ctx_sp->GetCFA(cursor_sp->cfa) == false ||
- abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) {
+ if (!reg_ctx_sp->TryFallbackUnwindPlan() ||
+ !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||
+ !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
// TryFallbackUnwindPlan for prev_frame succeeded and updated
// reg_ctx_lldb_sp field of prev_frame. However, cfa field of
@@ -383,10 +385,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
// Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already
// updated during TryFallbackUnwindPlan call above. However, cfa field
// still needs to be updated. Hence updating it here and then returning.
- if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
- m_frames[m_frames.size() - 2]->cfa)))
- return false;
- return true;
+ return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
+ m_frames[m_frames.size() - 2]->cfa);
}
// The new frame hasn't helped in unwinding. Fall back to the original one as
@@ -468,10 +468,7 @@ bool UnwindLLDB::SearchForSavedLocationForRegister(
UnwindLLDB::RegisterSearchResult result;
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
lldb_regnum, regloc);
- if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
- return true;
- else
- return false;
+ return result == UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
while (frame_num >= 0) {
UnwindLLDB::RegisterSearchResult result;
diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h
index 3d1f85a3dec3..aec7b66d9354 100644
--- a/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -10,12 +10,8 @@
#ifndef lldb_UnwindLLDB_h_
#define lldb_UnwindLLDB_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/UnwindPlan.h"
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index 2115b4e179c0..ae0b9fb0a526 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -114,7 +114,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
if (!m_cursors.empty()) {
lldb::addr_t first_frame_pc = m_cursors.front().pc;
if (first_frame_pc != LLDB_INVALID_ADDRESS) {
- const uint32_t resolve_scope =
+ const SymbolContextItem resolve_scope =
eSymbolContextModule | eSymbolContextCompUnit |
eSymbolContextFunction | eSymbolContextSymbol;
@@ -205,7 +205,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
if (!m_cursors.empty()) {
lldb::addr_t first_frame_pc = m_cursors.front().pc;
if (first_frame_pc != LLDB_INVALID_ADDRESS) {
- const uint32_t resolve_scope =
+ const SymbolContextItem resolve_scope =
eSymbolContextModule | eSymbolContextCompUnit |
eSymbolContextFunction | eSymbolContextSymbol;
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
index 328117a306ef..9ee0b08ca09a 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h
@@ -10,12 +10,8 @@
#ifndef lldb_UnwindMacOSXFrameBackchain_h_
#define lldb_UnwindMacOSXFrameBackchain_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Unwind.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
index ad43551a4c6d..81ec25871c57 100644
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -12,7 +12,6 @@
#include "IDebugDelegate.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Predicate.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/windows/HostProcessWindows.h"
#include "lldb/Host/windows/HostThreadWindows.h"
@@ -21,6 +20,7 @@
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/Status.h"
#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
@@ -50,7 +50,7 @@ struct DebugAttachContext {
lldb::pid_t m_pid;
ProcessAttachInfo m_attach_info;
};
-}
+} // namespace
DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
: m_debug_delegate(debug_delegate), m_pid_to_detach(0),
@@ -191,7 +191,8 @@ Status DebuggerThread::StopDebugging(bool terminate) {
handle, pid, terminate_suceeded);
} else {
LLDB_LOG(log,
- "NOT calling TerminateProcess because the inferior is not valid ({0}, 0) (inferior={1})",
+ "NOT calling TerminateProcess because the inferior is not valid "
+ "({0}, 0) (inferior={1})",
handle, pid);
}
}
@@ -267,6 +268,8 @@ void DebuggerThread::DebugLoop() {
if (wait_result) {
DWORD continue_status = DBG_CONTINUE;
switch (dbe.dwDebugEventCode) {
+ default:
+ llvm_unreachable("Unhandle debug event code!");
case EXCEPTION_DEBUG_EVENT: {
ExceptionResult status =
HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
@@ -330,7 +333,7 @@ void DebuggerThread::DebugLoop() {
FreeProcessHandles();
LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting.");
- SetEvent(m_debugging_ended_event);
+ ::SetEvent(m_debugging_ended_event);
}
ExceptionResult
@@ -381,7 +384,7 @@ DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
DWORD thread_id) {
Log *log =
ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "Thread {0:x} spawned in process {1}", thread_id,
+ LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
m_process.GetProcessId());
HostThread thread(info.hThread);
thread.GetNativeThread().SetOwnsHandle(false);
@@ -439,7 +442,6 @@ DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
m_debug_delegate->OnExitProcess(info.dwExitCode);
- FreeProcessHandles();
return DBG_CONTINUE;
}
@@ -468,7 +470,7 @@ DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
if (path_str.startswith("\\\\?\\"))
path += 4;
- FileSpec file_spec(path, false);
+ FileSpec file_spec(path);
ModuleSpec module_spec(file_spec);
lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h
index fcf36f7dec9b..047d3ccb7296 100644
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.h
+++ b/source/Plugins/Process/Windows/Common/DebuggerThread.h
@@ -16,8 +16,8 @@
#include "ForwardDecl.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Predicate.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/Utility/Predicate.h"
namespace lldb_private {
diff --git a/source/Plugins/Process/Windows/Common/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h
index cfe1b79cee11..ce2af3ca4111 100644
--- a/source/Plugins/Process/Windows/Common/ForwardDecl.h
+++ b/source/Plugins/Process/Windows/Common/ForwardDecl.h
@@ -39,4 +39,4 @@ typedef std::shared_ptr<ExceptionRecord> ExceptionRecordSP;
typedef std::unique_ptr<ExceptionRecord> ExceptionRecordUP;
}
-#endif \ No newline at end of file
+#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index b14081f76617..3fe5ab7804cb 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -13,12 +13,11 @@
#include "lldb/Host/windows/windows.h"
#include <psapi.h>
-// Other libraries and framework includes
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostNativeProcessBase.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/windows/HostThreadWindows.h"
@@ -28,6 +27,7 @@
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/State.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
@@ -72,6 +72,20 @@ std::string GetProcessExecutableName(DWORD pid) {
return file_name;
}
+DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
+ // We also can process a read / write permissions here, but if the debugger
+ // will make later a write into the allocated memory, it will fail. To get
+ // around it is possible inside DoWriteMemory to remember memory permissions,
+ // allow write, write and restore permissions, but for now we process only
+ // the executable permission.
+ //
+ // TODO: Process permissions other than executable
+ if (protect & ePermissionsExecutable)
+ return PAGE_EXECUTE_READWRITE;
+
+ return PAGE_READWRITE;
+}
+
} // anonymous namespace
namespace lldb_private {
@@ -237,11 +251,13 @@ Status ProcessWindows::DoLaunch(Module *exe_module,
FileSpec working_dir = launch_info.GetWorkingDirectory();
namespace fs = llvm::sys::fs;
- if (working_dir && (!working_dir.ResolvePath() ||
- !fs::is_directory(working_dir.GetPath()))) {
- result.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return result;
+ if (working_dir) {
+ FileSystem::Instance().Resolve(working_dir);
+ if (!FileSystem::Instance().IsDirectory(working_dir)) {
+ result.SetErrorStringWithFormat("No such file or directory: %s",
+ working_dir.GetCString());
+ return result;
+ }
}
if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
@@ -379,7 +395,7 @@ Status ProcessWindows::DoResume() {
SetPrivateState(eStateRunning);
}
} else {
- LLDB_LOG(log, "error: process %I64u is in state %u. Returning...",
+ LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
m_session_data->m_debugger->GetProcess().GetProcessId(),
GetPrivateState());
}
@@ -577,7 +593,7 @@ bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target_sp->GetExecutableModule());
if (exe_module_sp.get())
- return exe_module_sp->GetFileSpec().Exists();
+ return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
// However, if there is no executable module, we return true since we might
// be preparing to attach.
return true;
@@ -695,6 +711,58 @@ size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
return bytes_written;
}
+lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions,
+ Status &error) {
+ Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
+ llvm::sys::ScopedLock lock(m_mutex);
+ LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
+ permissions);
+
+ if (!m_session_data) {
+ LLDB_LOG(log, "cannot allocate, there is no active debugger connection.");
+ error.SetErrorString(
+ "cannot allocate, there is no active debugger connection");
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ auto protect = ConvertLldbToWinApiProtect(permissions);
+ auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
+ if (!result) {
+ error.SetError(GetLastError(), eErrorTypeWin32);
+ LLDB_LOG(log, "allocating failed with error: {0}", error);
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ return reinterpret_cast<addr_t>(result);
+}
+
+Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) {
+ Status result;
+
+ Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
+ llvm::sys::ScopedLock lock(m_mutex);
+ LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr);
+
+ if (!m_session_data) {
+ LLDB_LOG(log, "cannot deallocate, there is no active debugger connection.");
+ result.SetErrorString(
+ "cannot deallocate, there is no active debugger connection");
+ return result;
+ }
+
+ HostProcess process = m_session_data->m_debugger->GetProcess();
+ lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
+ if (!VirtualFreeEx(handle, reinterpret_cast<LPVOID>(ptr), 0, MEM_RELEASE)) {
+ result.SetError(GetLastError(), eErrorTypeWin32);
+ LLDB_LOG(log, "deallocating failed with error: {0}", result);
+ return result;
+ }
+
+ return result;
+}
+
Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
MemoryRegionInfo &info) {
Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
@@ -812,6 +880,14 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) {
SetProcessExitStatus(GetID(), true, 0, exit_code);
SetPrivateState(eStateExited);
+
+ // If the process exits before any initial stop then notify the debugger
+ // of the error otherwise WaitForDebuggerConnection() will be blocked.
+ // An example of this issue is when a process fails to load a dependent DLL.
+ if (m_session_data && !m_session_data->m_initial_stop_received) {
+ Status error(exit_code, eErrorTypeWin32);
+ OnDebuggerError(error, 0);
+ }
}
void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
@@ -829,7 +905,8 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
return;
}
- FileSpec executable_file(file_name, true);
+ FileSpec executable_file(file_name);
+ FileSystem::Instance().Resolve(executable_file);
ModuleSpec module_spec(executable_file);
Status error;
module = GetTarget().GetSharedModule(module_spec, &error);
@@ -837,7 +914,7 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
return;
}
- GetTarget().SetExecutableModule(module, false);
+ GetTarget().SetExecutableModule(module, eLoadDependentsNo);
}
bool load_addr_changed;
@@ -880,8 +957,9 @@ ProcessWindows::OnDebugException(bool first_chance,
}
if (!first_chance) {
- // Any second chance exception is an application crash by definition.
- SetPrivateState(eStateCrashed);
+ // Not any second chance exception is an application crash by definition.
+ // It may be an expression evaluation crash.
+ SetPrivateState(eStateStopped);
}
ExceptionResult result = ExceptionResult::SendToApplication;
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h
index ed3938beb347..00e384f58408 100644
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -10,7 +10,6 @@
#ifndef liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
-// Other libraries and framework includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-forward.h"
@@ -84,6 +83,9 @@ public:
Status &error) override;
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
Status &error) override;
+ lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+ Status &error) override;
+ Status DoDeallocateMemory(lldb::addr_t ptr) override;
Status GetMemoryRegionInfo(lldb::addr_t vm_addr,
MemoryRegionInfo &info) override;
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
index b3f507128f82..90d43b2cf828 100644
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
@@ -40,12 +40,13 @@ void RegisterContextWindows::InvalidateAllRegisters() {
bool RegisterContextWindows::ReadAllRegisterValues(
lldb::DataBufferSP &data_sp) {
+
if (!CacheAllRegisterValues())
return false;
- if (data_sp->GetByteSize() < sizeof(m_context)) {
- data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
- }
+
+ data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
+
return true;
}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
index 3903280918cc..b121dc7bf15e 100644
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThreadBase.h"
#include "lldb/Host/windows/HostThreadWindows.h"
@@ -15,6 +14,7 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
+#include "lldb/Utility/State.h"
#include "Plugins/Process/Utility/UnwindLLDB.h"
#include "ProcessWindows.h"
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
index 4aa6c785f83c..584136a6e5bb 100644
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-types.h"
@@ -74,12 +74,12 @@ RegisterInfo g_register_infos[] = {
nullptr,
nullptr},
{DEFINE_GPR(rcx, nullptr),
- {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1,
LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(rdx, nullptr),
- {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2,
LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
nullptr,
nullptr},
@@ -104,22 +104,22 @@ RegisterInfo g_register_infos[] = {
nullptr,
nullptr},
{DEFINE_GPR(r8, nullptr),
- {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3,
LLDB_INVALID_REGNUM, lldb_r8_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r9, nullptr),
- {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4,
LLDB_INVALID_REGNUM, lldb_r9_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5,
LLDB_INVALID_REGNUM, lldb_r10_x86_64},
nullptr,
nullptr},
{DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM,
+ {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6,
LLDB_INVALID_REGNUM, lldb_r11_x86_64},
nullptr,
nullptr},
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
index fd486f3d0829..e012f9105f31 100644
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-types.h"
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 7bb7b72eaac1..7d66461c15bc 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -7,25 +7,21 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stdlib.h>
-// C++ Includes
#include <mutex>
-// Other libraries and framework includes
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/Threading.h"
@@ -61,8 +57,8 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
// the header extension.
const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr);
- auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(),
- header_size, 0);
+ auto data_sp = FileSystem::Instance().CreateDataBuffer(
+ crash_file->GetPath(), header_size, 0);
if (data_sp && data_sp->GetByteSize() == header_size &&
elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) {
elf::ELFHeader elf_header;
@@ -81,7 +77,7 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp,
bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) {
// For now we are just making sure the file exists for a given module
- if (!m_core_module_sp && m_core_file.Exists()) {
+ if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture());
Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
NULL, NULL, NULL));
@@ -122,10 +118,10 @@ ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ProcessElfCore::GetPluginVersion() { return 1; }
lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
- const elf::ELFProgramHeader *header) {
- const lldb::addr_t addr = header->p_vaddr;
- FileRange file_range(header->p_offset, header->p_filesz);
- VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
+ const elf::ELFProgramHeader &header) {
+ const lldb::addr_t addr = header.p_vaddr;
+ FileRange file_range(header.p_offset, header.p_filesz);
+ VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range);
VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
@@ -140,12 +136,12 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment(
// Keep a separate map of permissions that that isn't coalesced so all ranges
// are maintained.
const uint32_t permissions =
- ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
- ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
- ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
+ ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) |
+ ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) |
+ ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u);
m_core_range_infos.Append(
- VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+ VMRangeToPermissions::Entry(addr, header.p_memsz, permissions));
return addr;
}
@@ -166,8 +162,8 @@ Status ProcessElfCore::DoLoadCore() {
return error;
}
- const uint32_t num_segments = core->GetProgramHeaderCount();
- if (num_segments == 0) {
+ llvm::ArrayRef<elf::ELFProgramHeader> segments = core->ProgramHeaders();
+ if (segments.size() == 0) {
error.SetErrorString("core file has no segments");
return error;
}
@@ -181,20 +177,17 @@ Status ProcessElfCore::DoLoadCore() {
/// Walk through segments and Thread and Address Map information.
/// PT_NOTE - Contains Thread and Register information
/// PT_LOAD - Contains a contiguous range of Process Address Space
- for (uint32_t i = 1; i <= num_segments; i++) {
- const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i);
- assert(header != NULL);
-
- DataExtractor data = core->GetSegmentDataByIndex(i);
+ for (const elf::ELFProgramHeader &H : segments) {
+ DataExtractor data = core->GetSegmentData(H);
// Parse thread contexts and auxv structure
- if (header->p_type == llvm::ELF::PT_NOTE) {
- if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data))
+ if (H.p_type == llvm::ELF::PT_NOTE) {
+ if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data))
return Status(std::move(error));
}
// PT_LOAD segments contains address map
- if (header->p_type == llvm::ELF::PT_LOAD) {
- lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header);
+ if (H.p_type == llvm::ELF::PT_LOAD) {
+ lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(H);
if (vm_addr > last_addr)
ranges_are_sorted = false;
vm_addr = last_addr;
@@ -249,12 +242,11 @@ Status ProcessElfCore::DoLoadCore() {
ModuleSpec exe_module_spec;
exe_module_spec.GetArchitecture() = arch;
exe_module_spec.GetFileSpec().SetFile(
- m_nt_file_entries[0].path.GetCString(), false,
- FileSpec::Style::native);
+ m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native);
if (exe_module_spec.GetFileSpec()) {
exe_module_sp = GetTarget().GetSharedModule(exe_module_spec);
if (exe_module_sp)
- GetTarget().SetExecutableModule(exe_module_sp, false);
+ GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo);
}
}
}
@@ -715,8 +707,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
/// 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);
+ const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) {
+ assert(segment_header.p_type == llvm::ELF::PT_NOTE);
auto notes_or_error = parseSegment(segment_data);
if(!notes_or_error)
@@ -744,8 +736,7 @@ uint32_t ProcessElfCore::GetNumThreadContexts() {
}
ArchSpec ProcessElfCore::GetArchitecture() {
- ArchSpec arch;
- m_core_module_sp->GetObjectFile()->GetArchitecture(arch);
+ ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture();
ArchSpec target_arch = GetTarget().GetArchitecture();
arch.MergeFrom(target_arch);
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index 325c0152e028..2c7268662fef 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -17,13 +17,9 @@
#ifndef liblldb_ProcessElfCore_h_
#define liblldb_ProcessElfCore_h_
-// C Includes
-// C++ Includes
#include <list>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
@@ -140,7 +136,7 @@ private:
// For ProcessElfCore only
//------------------------------------------------------------------
typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1>
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange>
VMRangeToFileOffset;
typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
VMRangeToPermissions;
@@ -170,7 +166,7 @@ private:
// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
llvm::Error ParseThreadContextsFromNoteSegment(
- const elf::ELFProgramHeader *segment_header,
+ const elf::ELFProgramHeader &segment_header,
lldb_private::DataExtractor segment_data);
// Returns number of thread contexts stored in the core file
@@ -178,7 +174,7 @@ private:
// Parse a contiguous address range of the process from LOAD segment
lldb::addr_t
- AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
+ AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader &header);
llvm::Expected<std::vector<lldb_private::CoreNote>>
parseSegment(const lldb_private::DataExtractor &segment);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 0d683153d9ed..80c6c0207a1e 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -9,8 +9,8 @@
#include "RegisterContextPOSIXCore_arm.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 919f8901d39a..017646b44b5c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -9,8 +9,8 @@
#include "RegisterContextPOSIXCore_arm64.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 532a1f5c0831..beeb9b666ccd 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -9,8 +9,8 @@
#include "RegisterContextPOSIXCore_mips64.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 8670e341a277..d4f86b354784 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -9,9 +9,9 @@
#include "RegisterContextPOSIXCore_powerpc.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
index 2237e72353ac..8116a1c7ea57 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
@@ -9,9 +9,9 @@
#include "RegisterContextPOSIXCore_ppc64le.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index f0edbf1ea854..875bb1647281 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -9,9 +9,9 @@
#include "RegisterContextPOSIXCore_s390x.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index a1f26d52444b..27295492f43d 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
#include "RegisterContextPOSIXCore_x86_64.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/RegisterValue.h"
using namespace lldb_private;
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 7ae25f83c5f8..4eb5291d54d5 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -15,6 +15,8 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
GDBRemoteCommunicationClient.cpp
+ GDBRemoteCommunicationHistory.cpp
+ GDBRemoteCommunicationReplayServer.cpp
GDBRemoteCommunicationServer.cpp
GDBRemoteCommunicationServerCommon.cpp
GDBRemoteCommunicationServerLLGS.cpp
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index 4e20b56fb111..a3a4aa053261 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -379,7 +379,7 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
m_comm.m_interrupt_time = steady_clock::now();
}
- m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
+ m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
m_did_interrupt = true;
}
m_acquired = true;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index c335b6002861..72c1314a7c94 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -9,21 +9,22 @@
#include "GDBRemoteCommunication.h"
-// C Includes
+#include <future>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
-// C++ Includes
-// Other libraries and framework includes
#include "lldb/Core/StreamFile.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/common/TCPSocket.h"
+#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/FileSpec.h"
@@ -33,7 +34,6 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ScopedPrinter.h"
-// Project includes
#include "ProcessGDBRemoteLog.h"
#if defined(__APPLE__)
@@ -42,7 +42,8 @@
#define DEBUGSERVER_BASENAME "lldb-server"
#endif
-#if defined(HAVE_LIBCOMPRESSION)
+#if defined(__APPLE__)
+#define HAVE_LIBCOMPRESSION
#include <compression.h>
#endif
@@ -54,78 +55,6 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
-GDBRemoteCommunication::History::History(uint32_t size)
- : m_packets(), m_curr_idx(0), m_total_packet_count(0),
- m_dumped_to_log(false) {
- m_packets.resize(size);
-}
-
-GDBRemoteCommunication::History::~History() {}
-
-void GDBRemoteCommunication::History::AddPacket(char packet_char,
- PacketType type,
- uint32_t bytes_transmitted) {
- const size_t size = m_packets.size();
- if (size > 0) {
- const uint32_t idx = GetNextIndex();
- m_packets[idx].packet.assign(1, packet_char);
- m_packets[idx].type = type;
- m_packets[idx].bytes_transmitted = bytes_transmitted;
- m_packets[idx].packet_idx = m_total_packet_count;
- m_packets[idx].tid = llvm::get_threadid();
- }
-}
-
-void GDBRemoteCommunication::History::AddPacket(const std::string &src,
- uint32_t src_len,
- PacketType type,
- uint32_t bytes_transmitted) {
- const size_t size = m_packets.size();
- if (size > 0) {
- const uint32_t idx = GetNextIndex();
- m_packets[idx].packet.assign(src, 0, src_len);
- m_packets[idx].type = type;
- m_packets[idx].bytes_transmitted = bytes_transmitted;
- m_packets[idx].packet_idx = m_total_packet_count;
- m_packets[idx].tid = llvm::get_threadid();
- }
-}
-
-void GDBRemoteCommunication::History::Dump(Stream &strm) const {
- const uint32_t size = GetNumPacketsInHistory();
- const uint32_t first_idx = GetFirstSavedPacketIndex();
- const uint32_t stop_idx = m_curr_idx + size;
- for (uint32_t i = first_idx; i < stop_idx; ++i) {
- const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.empty())
- break;
- strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.c_str());
- }
-}
-
-void GDBRemoteCommunication::History::Dump(Log *log) const {
- if (log && !m_dumped_to_log) {
- m_dumped_to_log = true;
- const uint32_t size = GetNumPacketsInHistory();
- const uint32_t first_idx = GetFirstSavedPacketIndex();
- const uint32_t stop_idx = m_curr_idx + size;
- for (uint32_t i = first_idx; i < stop_idx; ++i) {
- const uint32_t idx = NormalizeIndex(i);
- const Entry &entry = m_packets[idx];
- if (entry.type == ePacketTypeInvalid || entry.packet.empty())
- break;
- log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
- entry.packet_idx, entry.tid, entry.bytes_transmitted,
- (entry.type == ePacketTypeSend) ? "send" : "read",
- entry.packet.c_str());
- }
- }
-}
-
//----------------------------------------------------------------------
// GDBRemoteCommunication constructor
//----------------------------------------------------------------------
@@ -139,7 +68,10 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
#endif
m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
m_send_acks(true), m_compression_type(CompressionType::None),
- m_listen_url() {
+ m_listen_url(), m_decompression_scratch_type(CompressionType::None),
+ m_decompression_scratch(nullptr) {
+ // Unused unless HAVE_LIBCOMPRESSION is defined.
+ (void)m_decompression_scratch_type;
}
//----------------------------------------------------------------------
@@ -150,6 +82,9 @@ GDBRemoteCommunication::~GDBRemoteCommunication() {
Disconnect();
}
+ if (m_decompression_scratch)
+ free (m_decompression_scratch);
+
// Stop the communications read thread which is used to parse all incoming
// packets. This function will block until the read thread returns.
if (m_read_thread_enabled)
@@ -172,7 +107,8 @@ size_t GDBRemoteCommunication::SendAck() {
const size_t bytes_written = Write(&ch, 1, status, NULL);
if (log)
log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+ m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
+ bytes_written);
return bytes_written;
}
@@ -183,26 +119,31 @@ size_t GDBRemoteCommunication::SendNack() {
const size_t bytes_written = Write(&ch, 1, status, NULL);
if (log)
log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
- m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+ m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend,
+ bytes_written);
return bytes_written;
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
- if (IsConnected()) {
StreamString packet(0, 4, eByteOrderBig);
-
packet.PutChar('$');
packet.Write(payload.data(), payload.size());
packet.PutChar('#');
packet.PutHex8(CalculcateChecksum(payload));
+ std::string packet_str = packet.GetString();
+
+ return SendRawPacketNoLock(packet_str);
+}
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet,
+ bool skip_ack) {
+ if (IsConnected()) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
- // TODO: Don't shimmy through a std::string, just use StringRef.
- std::string packet_str = packet.GetString();
- const char *packet_data = packet_str.c_str();
- const size_t packet_length = packet.GetSize();
+ const char *packet_data = packet.data();
+ const size_t packet_length = packet.size();
size_t bytes_written = Write(packet_data, packet_length, status, NULL);
if (log) {
size_t binary_start_offset = 0;
@@ -241,11 +182,12 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
(int)packet_length, packet_data);
}
- m_history.AddPacket(packet.GetString(), packet_length,
- History::ePacketTypeSend, bytes_written);
+ m_history.AddPacket(packet.str(), packet_length,
+ GDBRemoteCommunicationHistory::ePacketTypeSend,
+ bytes_written);
if (bytes_written == packet_length) {
- if (GetSendAcks())
+ if (!skip_ack && GetSendAcks())
return GetAck();
else
return PacketResult::Success;
@@ -597,7 +539,7 @@ bool GDBRemoteCommunication::DecompressPacket() {
size_t decompressed_bytes = 0;
if (decompressed_bufsize != ULONG_MAX) {
- decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1);
+ decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize);
if (decompressed_buffer == nullptr) {
m_bytes.erase(0, size_of_first_packet);
return false;
@@ -605,11 +547,10 @@ bool GDBRemoteCommunication::DecompressPacket() {
}
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so check that compression_decode_buffer() is
- // available
if (m_compression_type == CompressionType::ZlibDeflate ||
m_compression_type == CompressionType::LZFSE ||
- m_compression_type == CompressionType::LZ4) {
+ m_compression_type == CompressionType::LZ4 ||
+ m_compression_type == CompressionType::LZMA) {
compression_algorithm compression_type;
if (m_compression_type == CompressionType::LZFSE)
compression_type = COMPRESSION_LZFSE;
@@ -620,16 +561,33 @@ bool GDBRemoteCommunication::DecompressPacket() {
else if (m_compression_type == CompressionType::LZMA)
compression_type = COMPRESSION_LZMA;
- // If we have the expected size of the decompressed payload, we can
- // allocate the right-sized buffer and do it. If we don't have that
- // information, we'll need to try decoding into a big buffer and if the
- // buffer wasn't big enough, increase it and try again.
+ if (m_decompression_scratch_type != m_compression_type) {
+ if (m_decompression_scratch) {
+ free (m_decompression_scratch);
+ m_decompression_scratch = nullptr;
+ }
+ size_t scratchbuf_size = 0;
+ if (m_compression_type == CompressionType::LZFSE)
+ scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
+ else if (m_compression_type == CompressionType::LZ4)
+ scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZ4_RAW);
+ else if (m_compression_type == CompressionType::ZlibDeflate)
+ scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_ZLIB);
+ else if (m_compression_type == CompressionType::LZMA)
+ scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZMA);
+ else if (m_compression_type == CompressionType::LZFSE)
+ scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
+ if (scratchbuf_size > 0) {
+ m_decompression_scratch = (void*) malloc (scratchbuf_size);
+ m_decompression_scratch_type = m_compression_type;
+ }
+ }
if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) {
decompressed_bytes = compression_decode_buffer(
- decompressed_buffer, decompressed_bufsize + 10,
- (uint8_t *)unescaped_content.data(), unescaped_content.size(), NULL,
- compression_type);
+ decompressed_buffer, decompressed_bufsize,
+ (uint8_t *)unescaped_content.data(), unescaped_content.size(),
+ m_decompression_scratch, compression_type);
}
}
#endif
@@ -721,7 +679,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// Size of packet before it is decompressed, for logging purposes
size_t original_packet_size = m_bytes.size();
if (CompressionIsEnabled()) {
- if (DecompressPacket() == false) {
+ if (!DecompressPacket()) {
packet.Clear();
return GDBRemoteCommunication::PacketType::Standard;
}
@@ -860,7 +818,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
}
}
- m_history.AddPacket(m_bytes, total_length, History::ePacketTypeRecv,
+ m_history.AddPacket(m_bytes, total_length,
+ GDBRemoteCommunicationHistory::ePacketTypeRecv,
total_length);
// Clear packet_str in case there is some existing data in it.
@@ -997,7 +956,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
// debugserver to use and use it if we do.
const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
if (env_debugserver_path) {
- debugserver_file_spec.SetFile(env_debugserver_path, false,
+ debugserver_file_spec.SetFile(env_debugserver_path,
FileSpec::Style::native);
if (log)
log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
@@ -1005,13 +964,14 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
__FUNCTION__, env_debugserver_path);
} else
debugserver_file_spec = g_debugserver_file_spec;
- bool debugserver_exists = debugserver_file_spec.Exists();
+ bool debugserver_exists =
+ FileSystem::Instance().Exists(debugserver_file_spec);
if (!debugserver_exists) {
// The debugserver binary is in the LLDB.framework/Resources directory.
debugserver_file_spec = HostInfo::GetSupportExeDir();
if (debugserver_file_spec) {
debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
- debugserver_exists = debugserver_file_spec.Exists();
+ debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec);
if (debugserver_exists) {
if (log)
log->Printf(
@@ -1074,7 +1034,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
debugserver_args.AppendArgument(llvm::StringRef("--setsid"));
}
- llvm::SmallString<PATH_MAX> named_pipe_path;
+ llvm::SmallString<128> named_pipe_path;
// socket_pipe is used by debug server to communicate back either
// TCP port or domain socket name which it listens on.
// The second purpose of the pipe to serve as a synchronization point -
@@ -1114,9 +1074,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
__FUNCTION__, error.AsCString());
return error;
}
- int write_fd = socket_pipe.GetWriteFileDescriptor();
+ pipe_t write = socket_pipe.GetWritePipe();
debugserver_args.AppendArgument(llvm::StringRef("--pipe"));
- debugserver_args.AppendArgument(llvm::to_string(write_fd));
+ debugserver_args.AppendArgument(llvm::to_string(write));
launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
#endif
} else {
@@ -1304,6 +1264,42 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
+void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) {
+ m_history.SetStream(strm);
+};
+
+llvm::Error
+GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client,
+ GDBRemoteCommunication &server) {
+ const bool child_processes_inherit = false;
+ const int backlog = 5;
+ TCPSocket listen_socket(true, child_processes_inherit);
+ if (llvm::Error error =
+ listen_socket.Listen("127.0.0.1:0", backlog).ToError())
+ return error;
+
+ Socket *accept_socket;
+ std::future<Status> accept_status = std::async(
+ std::launch::async, [&] { return listen_socket.Accept(accept_socket); });
+
+ llvm::SmallString<32> remote_addr;
+ llvm::raw_svector_ostream(remote_addr)
+ << "connect://localhost:" << listen_socket.GetLocalPortNumber();
+
+ std::unique_ptr<ConnectionFileDescriptor> conn_up(
+ new ConnectionFileDescriptor());
+ if (conn_up->Connect(remote_addr, nullptr) != lldb::eConnectionStatusSuccess)
+ return llvm::make_error<llvm::StringError>("Unable to connect",
+ llvm::inconvertibleErrorCode());
+
+ client.SetConnection(conn_up.release());
+ if (llvm::Error error = accept_status.get().ToError())
+ return error;
+
+ server.SetConnection(new ConnectionFileDescriptor(accept_socket));
+ return llvm::Error::success();
+}
+
GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout)
: m_gdb_comm(gdb_comm), m_timeout_modified(false) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 67796e4c61ef..369eb25b1dfa 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -10,24 +10,21 @@
#ifndef liblldb_GDBRemoteCommunication_h_
#define liblldb_GDBRemoteCommunication_h_
-// C Includes
-// C++ Includes
+#include "GDBRemoteCommunicationHistory.h"
+
#include <condition_variable>
#include <mutex>
#include <queue>
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Communication.h"
-#include "lldb/Core/Listener.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/Predicate.h"
#include "lldb/Utility/Args.h"
-#include "lldb/lldb-public.h"
-
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
+#include "lldb/lldb-public.h"
namespace lldb_private {
namespace process_gdb_remote {
@@ -140,86 +137,16 @@ public:
// fork/exec to avoid having to connect/accept
void DumpHistory(Stream &strm);
+ void SetHistoryStream(llvm::raw_ostream *strm);
-protected:
- class History {
- public:
- enum PacketType {
- ePacketTypeInvalid = 0,
- ePacketTypeSend,
- ePacketTypeRecv
- };
-
- struct Entry {
- Entry()
- : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
- packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
-
- void Clear() {
- packet.clear();
- type = ePacketTypeInvalid;
- bytes_transmitted = 0;
- packet_idx = 0;
- tid = LLDB_INVALID_THREAD_ID;
- }
- std::string packet;
- PacketType type;
- uint32_t bytes_transmitted;
- uint32_t packet_idx;
- lldb::tid_t tid;
- };
-
- History(uint32_t size);
-
- ~History();
-
- // For single char packets for ack, nack and /x03
- void AddPacket(char packet_char, PacketType type,
- uint32_t bytes_transmitted);
-
- void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
- uint32_t bytes_transmitted);
-
- void Dump(Stream &strm) const;
-
- void Dump(Log *log) const;
-
- bool DidDumpToLog() const { return m_dumped_to_log; }
-
- protected:
- uint32_t GetFirstSavedPacketIndex() const {
- if (m_total_packet_count < m_packets.size())
- return 0;
- else
- return m_curr_idx + 1;
- }
-
- uint32_t GetNumPacketsInHistory() const {
- if (m_total_packet_count < m_packets.size())
- return m_total_packet_count;
- else
- return (uint32_t)m_packets.size();
- }
-
- uint32_t GetNextIndex() {
- ++m_total_packet_count;
- const uint32_t idx = m_curr_idx;
- m_curr_idx = NormalizeIndex(idx + 1);
- return idx;
- }
-
- uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); }
-
- std::vector<Entry> m_packets;
- uint32_t m_curr_idx;
- uint32_t m_total_packet_count;
- mutable bool m_dumped_to_log;
- };
+ static llvm::Error ConnectLocally(GDBRemoteCommunication &client,
+ GDBRemoteCommunication &server);
+protected:
std::chrono::seconds m_packet_timeout;
uint32_t m_echo_number;
LazyBool m_supports_qEcho;
- History m_history;
+ GDBRemoteCommunicationHistory m_history;
bool m_send_acks;
bool m_is_platform; // Set to true if this class represents a platform,
// false if this class represents a debug session for
@@ -228,6 +155,8 @@ protected:
CompressionType m_compression_type;
PacketResult SendPacketNoLock(llvm::StringRef payload);
+ PacketResult SendRawPacketNoLock(llvm::StringRef payload,
+ bool skip_ack = false);
PacketResult ReadPacket(StringExtractorGDBRemote &response,
Timeout<std::micro> timeout, bool sync_on_timeout);
@@ -289,6 +218,9 @@ private:
HostThread m_listen_thread;
std::string m_listen_url;
+ CompressionType m_decompression_scratch_type;
+ void *m_decompression_scratch;
+
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
};
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c8b59d5d236b..1e12ea6b2d56 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -9,17 +9,13 @@
#include "GDBRemoteCommunicationClient.h"
-// C Includes
#include <math.h>
#include <sys/stat.h>
-// C++ Includes
#include <numeric>
#include <sstream>
-// Other libraries and framework includes
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/Symbol.h"
@@ -31,9 +27,9 @@
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
-// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Host/Config.h"
@@ -41,7 +37,8 @@
#include "llvm/ADT/StringSwitch.h"
-#if defined(HAVE_LIBCOMPRESSION)
+#if defined(__APPLE__)
+#define HAVE_LIBCOMPRESSION
#include <compression.h>
#endif
@@ -256,10 +253,7 @@ bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
m_attach_or_wait_reply = eLazyBoolYes;
}
}
- if (m_attach_or_wait_reply == eLazyBoolYes)
- return true;
- else
- return false;
+ return m_attach_or_wait_reply == eLazyBoolYes;
}
bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
@@ -273,14 +267,11 @@ bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
m_prepare_for_reg_writing_reply = eLazyBoolYes;
}
}
- if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
- return true;
- else
- return false;
+ return m_prepare_for_reg_writing_reply == eLazyBoolYes;
}
void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
- if (did_exec == false) {
+ if (!did_exec) {
// Hard reset everything, this is when we first connect to a GDB server
m_supports_not_sending_acks = eLazyBoolCalculate;
m_supports_thread_suffix = eLazyBoolCalculate;
@@ -749,7 +740,7 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
bool sequence_mutex_unavailable;
size_t size;
size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable);
- if (size && sequence_mutex_unavailable == false) {
+ if (size && !sequence_mutex_unavailable) {
m_curr_pid = thread_ids.front();
m_curr_pid_is_valid = eLazyBoolYes;
return m_curr_pid;
@@ -843,8 +834,8 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket(
if (name_equal_value && name_equal_value[0]) {
StreamString packet;
bool send_hex_encoding = false;
- for (const char *p = name_equal_value;
- *p != '\0' && send_hex_encoding == false; ++p) {
+ for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
+ ++p) {
if (isprint(*p)) {
switch (*p) {
case '$':
@@ -1134,6 +1125,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
+ // host info computation can require DNS traffic and shelling out to external processes.
+ // Increase the timeout to account for that.
+ ScopedTimeout timeout(*this, seconds(10));
m_qHostInfo_is_valid = eLazyBoolNo;
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
@@ -1686,12 +1680,17 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
m_supports_watchpoint_support_info = eLazyBoolYes;
llvm::StringRef name;
llvm::StringRef value;
+ bool found_num_field = false;
while (response.GetNameColonValue(name, value)) {
if (name.equals("num")) {
value.getAsInteger(0, m_num_supported_hardware_watchpoints);
num = m_num_supported_hardware_watchpoints;
+ found_num_field = true;
}
}
+ if (!found_num_field) {
+ m_supports_watchpoint_support_info = eLazyBoolNo;
+ }
} else {
m_supports_watchpoint_support_info = eLazyBoolNo;
}
@@ -1724,12 +1723,10 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
// 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::ppc64le)
- after = false;
- else
- after = true;
+ after =
+ !(atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
+ atype == llvm::Triple::ppc64le);
} else {
// For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
// eLazyBoolNo if it is not calculated before.
@@ -1815,7 +1812,7 @@ bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
return false;
std::string cwd;
response.GetHexByteString(cwd);
- working_dir.SetFile(cwd, false, GetHostArchitecture().GetTriple());
+ working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
return !cwd.empty();
}
return false;
@@ -1925,8 +1922,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
// characters in a process name
std::string name;
extractor.GetHexByteString(name);
- process_info.GetExecutableFile().SetFile(name, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
} else if (name.equals("cputype")) {
value.getAsInteger(0, cpu);
} else if (name.equals("cpusubtype")) {
@@ -3559,7 +3555,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo(
StringExtractor extractor(value);
std::string path;
extractor.GetHexByteString(path);
- module_spec.GetFileSpec() = FileSpec(path, false, arch_spec.GetTriple());
+ module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
}
}
@@ -3595,8 +3591,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
if (!dict->GetValueForKeyAsString("file_path", string))
return llvm::None;
- result.GetFileSpec() =
- FileSpec(string, false, result.GetArchitecture().GetTriple());
+ result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());
return result;
}
@@ -3774,7 +3769,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
// Is this the initial qSymbol:: packet?
bool first_qsymbol_query = true;
- if (m_supports_qSymbol && m_qSymbol_requests_done == false) {
+ if (m_supports_qSymbol && !m_qSymbol_requests_done) {
Lock lock(*this, false);
if (lock) {
StreamString packet;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index cf1d249768d7..37d53ab425f5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -12,8 +12,6 @@
#include "GDBRemoteClientBase.h"
-// C Includes
-// C++ Includes
#include <chrono>
#include <map>
#include <mutex>
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
new file mode 100644
index 000000000000..69b13f2a3acb
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp
@@ -0,0 +1,143 @@
+//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "GDBRemoteCommunicationHistory.h"
+
+// Other libraries and framework includes
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Log.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+
+void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const {
+ yaml::Output yout(strm);
+ yout << const_cast<GDBRemoteCommunicationHistory::Entry &>(*this);
+ strm.flush();
+}
+
+GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
+ : m_packets(), m_curr_idx(0), m_total_packet_count(0),
+ m_dumped_to_log(false) {
+ if (size)
+ m_packets.resize(size);
+}
+
+GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}
+
+void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type,
+ uint32_t bytes_transmitted) {
+ const size_t size = m_packets.size();
+ if (size == 0)
+ return;
+
+ const uint32_t idx = GetNextIndex();
+ m_packets[idx].packet.data.assign(1, packet_char);
+ m_packets[idx].type = type;
+ m_packets[idx].bytes_transmitted = bytes_transmitted;
+ m_packets[idx].packet_idx = m_total_packet_count;
+ m_packets[idx].tid = llvm::get_threadid();
+ if (m_stream && type == ePacketTypeRecv)
+ m_packets[idx].Serialize(*m_stream);
+}
+
+void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
+ uint32_t src_len, PacketType type,
+ uint32_t bytes_transmitted) {
+ const size_t size = m_packets.size();
+ if (size == 0)
+ return;
+
+ const uint32_t idx = GetNextIndex();
+ m_packets[idx].packet.data.assign(src, 0, src_len);
+ m_packets[idx].type = type;
+ m_packets[idx].bytes_transmitted = bytes_transmitted;
+ m_packets[idx].packet_idx = m_total_packet_count;
+ m_packets[idx].tid = llvm::get_threadid();
+ if (m_stream && type == ePacketTypeRecv)
+ m_packets[idx].Serialize(*m_stream);
+}
+
+void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
+ const uint32_t size = GetNumPacketsInHistory();
+ const uint32_t first_idx = GetFirstSavedPacketIndex();
+ const uint32_t stop_idx = m_curr_idx + size;
+ for (uint32_t i = first_idx; i < stop_idx; ++i) {
+ const uint32_t idx = NormalizeIndex(i);
+ const Entry &entry = m_packets[idx];
+ if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ break;
+ strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == ePacketTypeSend) ? "send" : "read",
+ entry.packet.data.c_str());
+ }
+}
+
+void GDBRemoteCommunicationHistory::Dump(Log *log) const {
+ if (!log || m_dumped_to_log)
+ return;
+
+ m_dumped_to_log = true;
+ const uint32_t size = GetNumPacketsInHistory();
+ const uint32_t first_idx = GetFirstSavedPacketIndex();
+ const uint32_t stop_idx = m_curr_idx + size;
+ for (uint32_t i = first_idx; i < stop_idx; ++i) {
+ const uint32_t idx = NormalizeIndex(i);
+ const Entry &entry = m_packets[idx];
+ if (entry.type == ePacketTypeInvalid || entry.packet.data.empty())
+ break;
+ log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
+ entry.packet_idx, entry.tid, entry.bytes_transmitted,
+ (entry.type == ePacketTypeSend) ? "send" : "read",
+ entry.packet.data.c_str());
+ }
+}
+
+void yaml::ScalarEnumerationTraits<GDBRemoteCommunicationHistory::PacketType>::
+ enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) {
+ io.enumCase(value, "Invalid",
+ GDBRemoteCommunicationHistory::ePacketTypeInvalid);
+ io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend);
+ io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv);
+}
+
+void yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::
+ output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *,
+ raw_ostream &Out) {
+ Out << toHex(Val.data);
+}
+
+StringRef
+yaml::ScalarTraits<GDBRemoteCommunicationHistory::Entry::BinaryData>::input(
+ StringRef Scalar, void *,
+ GDBRemoteCommunicationHistory::Entry::BinaryData &Val) {
+ Val.data = fromHex(Scalar);
+ return {};
+}
+
+void yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::mapping(
+ IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
+ io.mapRequired("packet", Entry.packet);
+ io.mapRequired("type", Entry.type);
+ io.mapRequired("bytes", Entry.bytes_transmitted);
+ io.mapRequired("index", Entry.packet_idx);
+ io.mapRequired("tid", Entry.tid);
+}
+
+StringRef yaml::MappingTraits<GDBRemoteCommunicationHistory::Entry>::validate(
+ IO &io, GDBRemoteCommunicationHistory::Entry &Entry) {
+ if (Entry.bytes_transmitted != Entry.packet.data.size())
+ return "BinaryData size doesn't match bytes transmitted";
+
+ return {};
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
new file mode 100644
index 000000000000..d0ca6a0235c9
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h
@@ -0,0 +1,156 @@
+//===-- GDBRemoteCommunicationHistory.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_GDBRemoteCommunicationHistory_h_
+#define liblldb_GDBRemoteCommunicationHistory_h_
+
+#include <string>
+#include <vector>
+
+#include "lldb/lldb-public.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+/// The history keeps a circular buffer of GDB remote packets. The history is
+/// used for logging and replaying GDB remote packets.
+class GDBRemoteCommunicationHistory {
+public:
+ friend llvm::yaml::MappingTraits<GDBRemoteCommunicationHistory>;
+
+ enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv };
+
+ /// Entry in the ring buffer containing the packet data, its type, size and
+ /// index. Entries can be serialized to file.
+ struct Entry {
+ Entry()
+ : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
+ packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
+
+ void Clear() {
+ packet.data.clear();
+ type = ePacketTypeInvalid;
+ bytes_transmitted = 0;
+ packet_idx = 0;
+ tid = LLDB_INVALID_THREAD_ID;
+ }
+
+ struct BinaryData {
+ std::string data;
+ };
+
+ void Serialize(llvm::raw_ostream &strm) const;
+
+ BinaryData packet;
+ PacketType type;
+ uint32_t bytes_transmitted;
+ uint32_t packet_idx;
+ lldb::tid_t tid;
+ };
+
+ GDBRemoteCommunicationHistory(uint32_t size = 0);
+
+ ~GDBRemoteCommunicationHistory();
+
+ // For single char packets for ack, nack and /x03
+ void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted);
+
+ void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+ uint32_t bytes_transmitted);
+
+ void Dump(Stream &strm) const;
+ void Dump(Log *log) const;
+ bool DidDumpToLog() const { return m_dumped_to_log; }
+
+ void SetStream(llvm::raw_ostream *strm) { m_stream = strm; }
+
+private:
+ uint32_t GetFirstSavedPacketIndex() const {
+ if (m_total_packet_count < m_packets.size())
+ return 0;
+ else
+ return m_curr_idx + 1;
+ }
+
+ uint32_t GetNumPacketsInHistory() const {
+ if (m_total_packet_count < m_packets.size())
+ return m_total_packet_count;
+ else
+ return (uint32_t)m_packets.size();
+ }
+
+ uint32_t GetNextIndex() {
+ ++m_total_packet_count;
+ const uint32_t idx = m_curr_idx;
+ m_curr_idx = NormalizeIndex(idx + 1);
+ return idx;
+ }
+
+ uint32_t NormalizeIndex(uint32_t i) const {
+ return m_packets.empty() ? 0 : i % m_packets.size();
+ }
+
+ std::vector<Entry> m_packets;
+ uint32_t m_curr_idx;
+ uint32_t m_total_packet_count;
+ mutable bool m_dumped_to_log;
+ llvm::raw_ostream *m_stream = nullptr;
+};
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry)
+
+namespace llvm {
+namespace yaml {
+
+template <>
+struct ScalarEnumerationTraits<lldb_private::process_gdb_remote::
+ GDBRemoteCommunicationHistory::PacketType> {
+ static void enumeration(IO &io,
+ lldb_private::process_gdb_remote::
+ GDBRemoteCommunicationHistory::PacketType &value);
+};
+
+template <>
+struct ScalarTraits<lldb_private::process_gdb_remote::
+ GDBRemoteCommunicationHistory::Entry::BinaryData> {
+ static void output(const lldb_private::process_gdb_remote::
+ GDBRemoteCommunicationHistory::Entry::BinaryData &,
+ void *, raw_ostream &);
+
+ static StringRef
+ input(StringRef, void *,
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry::
+ BinaryData &);
+
+ static QuotingType mustQuote(StringRef S) { return QuotingType::None; }
+};
+
+template <>
+struct MappingTraits<
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> {
+ static void
+ mapping(IO &io,
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry
+ &Entry);
+
+ static StringRef validate(
+ IO &io,
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &);
+};
+
+} // namespace yaml
+} // namespace llvm
+
+#endif // liblldb_GDBRemoteCommunicationHistory_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
new file mode 100644
index 000000000000..6a78eb20992e
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp
@@ -0,0 +1,204 @@
+//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <errno.h>
+
+#include "lldb/Host/Config.h"
+
+#include "GDBRemoteCommunicationReplayServer.h"
+#include "ProcessGDBRemoteLog.h"
+
+// C Includes
+// C++ Includes
+#include <cstring>
+
+// Project includes
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StringExtractorGDBRemote.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_gdb_remote;
+
+GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer()
+ : GDBRemoteCommunication("gdb-remote.server",
+ "gdb-remote.server.rx_packet"),
+ m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"),
+ m_async_listener_sp(
+ Listener::MakeListener("lldb.gdb-remote.server.async-listener")),
+ m_async_thread_state_mutex(), m_skip_acks(false) {
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+ "async thread continue");
+ m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+ "async thread should exit");
+
+ const uint32_t async_event_mask =
+ eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+ m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster,
+ async_event_mask);
+}
+
+GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() {
+ StopAsyncThread();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse(
+ Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
+ StringExtractorGDBRemote packet;
+ PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
+
+ if (packet_result != PacketResult::Success) {
+ if (!IsConnected()) {
+ error.SetErrorString("lost connection");
+ quit = true;
+ } else {
+ error.SetErrorString("timeout");
+ }
+ return packet_result;
+ }
+
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
+
+ if (m_skip_acks) {
+ const StringExtractorGDBRemote::ServerPacketType packet_type =
+ packet.GetServerPacketType();
+ switch (packet_type) {
+ case StringExtractorGDBRemote::eServerPacketType_nack:
+ case StringExtractorGDBRemote::eServerPacketType_ack:
+ return PacketResult::Success;
+ default:
+ break;
+ }
+ } else if (packet.GetStringRef() == "QStartNoAckMode") {
+ m_skip_acks = true;
+ m_send_acks = false;
+ }
+
+ while (!m_packet_history.empty()) {
+ // Pop last packet from the history.
+ GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back();
+ m_packet_history.pop_back();
+
+ // We only care about what we received from the server. Skip everything
+ // the client sent.
+ if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv)
+ continue;
+
+ return SendRawPacketNoLock(entry.packet.data, true);
+ }
+
+ quit = true;
+
+ return packet_result;
+}
+
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(
+ std::vector<
+ lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>)
+
+llvm::Error
+GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) {
+ auto error_or_file = MemoryBuffer::getFile(path.GetPath());
+ if (auto err = error_or_file.getError())
+ return errorCodeToError(err);
+
+ yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> m_packet_history;
+
+ if (auto err = yin.error())
+ return errorCodeToError(err);
+
+ // We want to manipulate the vector like a stack so we need to reverse the
+ // order of the packets to have the oldest on at the back.
+ std::reverse(m_packet_history.begin(), m_packet_history.end());
+
+ return Error::success();
+}
+
+bool GDBRemoteCommunicationReplayServer::StartAsyncThread() {
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+ if (!m_async_thread.IsJoinable()) {
+ // Create a thread that watches our internal state and controls which
+ // events make it to clients (into the DCProcess event queue).
+ m_async_thread = ThreadLauncher::LaunchThread(
+ "<lldb.gdb-remote.server.async>",
+ GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr);
+ }
+
+ // Wait for handshake.
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
+
+ return m_async_thread.IsJoinable();
+}
+
+void GDBRemoteCommunicationReplayServer::StopAsyncThread() {
+ std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+
+ if (!m_async_thread.IsJoinable())
+ return;
+
+ // Request thread to stop.
+ m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
+
+ // Disconnect client.
+ Disconnect();
+
+ // Stop the thread.
+ m_async_thread.Join(nullptr);
+ m_async_thread.Reset();
+}
+
+void GDBRemoteCommunicationReplayServer::ReceivePacket(
+ GDBRemoteCommunicationReplayServer &server, bool &done) {
+ Status error;
+ bool interrupt;
+ auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1),
+ error, interrupt, done);
+ if (packet_result != GDBRemoteCommunication::PacketResult::Success &&
+ packet_result !=
+ GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) {
+ done = true;
+ } else {
+ server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
+ }
+}
+
+thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) {
+ GDBRemoteCommunicationReplayServer *server =
+ (GDBRemoteCommunicationReplayServer *)arg;
+
+ EventSP event_sp;
+ bool done = false;
+
+ while (true) {
+ if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) {
+ const uint32_t event_type = event_sp->GetType();
+ if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) {
+ switch (event_type) {
+ case eBroadcastBitAsyncContinue:
+ ReceivePacket(*server, done);
+ if (done)
+ return {};
+ break;
+ case eBroadcastBitAsyncThreadShouldExit:
+ default:
+ return {};
+ }
+ }
+ }
+ }
+
+ return {};
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
new file mode 100644
index 000000000000..5b840c8459b7
--- /dev/null
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h
@@ -0,0 +1,83 @@
+//===-- GDBRemoteCommunicationReplayServer.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_GDBRemoteCommunicationReplayServer_h_
+#define liblldb_GDBRemoteCommunicationReplayServer_h_
+
+// Other libraries and framework includes
+#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationHistory.h"
+
+// Project includes
+#include "lldb/Host/HostThread.h"
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/lldb-private-forward.h"
+#include "llvm/Support/Error.h"
+
+// C Includes
+// C++ Includes
+#include <functional>
+#include <map>
+#include <thread>
+
+class StringExtractorGDBRemote;
+
+namespace lldb_private {
+namespace process_gdb_remote {
+
+class ProcessGDBRemote;
+
+/// Dummy GDB server that replays packets from the GDB Remote Communication
+/// history. This is used to replay GDB packets.
+class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication {
+public:
+ GDBRemoteCommunicationReplayServer();
+
+ ~GDBRemoteCommunicationReplayServer() override;
+
+ PacketResult GetPacketAndSendResponse(Timeout<std::micro> timeout,
+ Status &error, bool &interrupt,
+ bool &quit);
+
+ bool HandshakeWithClient() { return GetAck() == PacketResult::Success; }
+
+ llvm::Error LoadReplayHistory(const FileSpec &path);
+
+ bool StartAsyncThread();
+ void StopAsyncThread();
+
+protected:
+ enum {
+ eBroadcastBitAsyncContinue = (1 << 0),
+ eBroadcastBitAsyncThreadShouldExit = (1 << 1),
+ };
+
+ static void ReceivePacket(GDBRemoteCommunicationReplayServer &server,
+ bool &done);
+ static lldb::thread_result_t AsyncThread(void *arg);
+
+ /// Replay history with the oldest packet at the end.
+ std::vector<GDBRemoteCommunicationHistory::Entry> m_packet_history;
+
+ /// Server thread.
+ Broadcaster m_async_broadcaster;
+ lldb::ListenerSP m_async_listener_sp;
+ HostThread m_async_thread;
+ std::recursive_mutex m_async_thread_state_mutex;
+
+ bool m_skip_acks;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer);
+};
+
+} // namespace process_gdb_remote
+} // namespace lldb_private
+
+#endif // liblldb_GDBRemoteCommunicationReplayServer_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 4fc1fc7a1964..026f78117a0c 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -13,11 +13,8 @@
#include "GDBRemoteCommunicationServer.h"
-// C Includes
-// C++ Includes
#include <cstring>
-// Project includes
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 880caacd6414..082fb0d85424 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -10,13 +10,9 @@
#ifndef liblldb_GDBRemoteCommunicationServer_h_
#define liblldb_GDBRemoteCommunicationServer_h_
-// C Includes
-// C++ Includes
#include <functional>
#include <map>
-// Other libraries and framework includes
-// Project includes
#include "GDBRemoteCommunication.h"
#include "lldb/lldb-private-forward.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index c5b478378faa..f11ef4f1bbf8 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -11,23 +11,21 @@
#include <errno.h>
-// C Includes
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
-// C++ Includes
#include <chrono>
#include <cstring>
-// Other libraries and framework includes
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/SafeMachO.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/FileAction.h"
@@ -36,12 +34,10 @@
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/Triple.h"
-// Project includes
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
@@ -353,7 +349,7 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
std::string file;
extractor.GetHexByteString(file);
match_info.GetProcessInfo().GetExecutableFile().SetFile(
- file, false, FileSpec::Style::native);
+ file, FileSpec::Style::native);
} else if (key.equals("name_match")) {
NameMatch name_match = llvm::StringSwitch<NameMatch>(value)
.Case("equals", NameMatch::Equals)
@@ -520,7 +516,8 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
if (packet.GetChar() == ',') {
mode_t mode = packet.GetHexMaxU32(false, 0600);
Status error;
- const FileSpec path_spec{path, true};
+ FileSpec path_spec(path);
+ FileSystem::Instance().Resolve(path_spec);
int fd = ::open(path_spec.GetCString(), flags, mode);
const int save_errno = fd == -1 ? errno : 0;
StreamString response;
@@ -659,12 +656,14 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
std::string path;
packet.GetHexByteString(path);
if (!path.empty()) {
- Status error;
- const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
+ std::error_code ec;
+ const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec);
StreamString response;
response.Printf("F%u", mode);
- if (mode == 0 || error.Fail())
- response.Printf(",%i", (int)error.GetError());
+ if (mode == 0 || ec)
+ response.Printf(",%i", (int)Status(ec).GetError());
return SendPacketNoLock(response.GetString());
}
return SendErrorResponse(23);
@@ -698,7 +697,11 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
packet.GetHexByteStringTerminatedBy(dst, ',');
packet.GetChar(); // Skip ',' char
packet.GetHexByteString(src);
- Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+
+ FileSpec src_spec(src);
+ FileSystem::Instance().Resolve(src_spec);
+ Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst));
+
StreamString response;
response.Printf("F%u,%u", error.GetError(), error.GetError());
return SendPacketNoLock(response.GetString());
@@ -731,9 +734,11 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
packet.GetHexByteString(working_dir);
int status, signo;
std::string output;
- Status err = Host::RunShellCommand(
- path.c_str(), FileSpec{working_dir, true}, &status, &signo, &output,
- std::chrono::seconds(10));
+ FileSpec working_spec(working_dir);
+ FileSystem::Instance().Resolve(working_spec);
+ Status err =
+ Host::RunShellCommand(path.c_str(), working_spec, &status, &signo,
+ &output, std::chrono::seconds(10));
StreamGDBRemote response;
if (err.Fail()) {
response.PutCString("F,");
@@ -884,7 +889,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
packet.GetHexByteString(path);
const bool read = true;
const bool write = false;
- if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -900,7 +905,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
packet.GetHexByteString(path);
const bool read = false;
const bool write = true;
- if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -916,7 +921,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
packet.GetHexByteString(path);
const bool read = false;
const bool write = true;
- if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) {
+ if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) {
m_process_launch_info.AppendFileAction(file_action);
return SendOKResponse();
}
@@ -1024,7 +1029,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (success) {
if (arg_idx == 0)
m_process_launch_info.GetExecutableFile().SetFile(
- arg, false, FileSpec::Style::native);
+ arg, FileSpec::Style::native);
m_process_launch_info.GetArguments().AppendArgument(arg);
if (log)
log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
@@ -1263,7 +1268,9 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
#ifdef __ANDROID__
return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
#else
- return FileSpec(module_path, true);
+ FileSpec file_spec(module_path);
+ FileSystem::Instance().Resolve(file_spec);
+ return file_spec;
#endif
}
@@ -1272,7 +1279,9 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path,
llvm::StringRef triple) {
ArchSpec arch(triple);
- const FileSpec req_module_path_spec(module_path, true);
+ FileSpec req_module_path_spec(module_path);
+ FileSystem::Instance().Resolve(req_module_path_spec);
+
const FileSpec module_path_spec =
FindModuleFile(req_module_path_spec.GetPath(), arch);
const ModuleSpec module_spec(module_path_spec, arch);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index e9ab8f1a11de..f3825bb36791 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -10,12 +10,8 @@
#ifndef liblldb_GDBRemoteCommunicationServerCommon_h_
#define liblldb_GDBRemoteCommunicationServerCommon_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/lldb-private-forward.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 50392fa38956..cdb63e72f6bd 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -14,15 +14,10 @@
#include "GDBRemoteCommunicationServerLLGS.h"
#include "lldb/Utility/StreamGDBRemote.h"
-// C Includes
-// C++ Includes
#include <chrono>
#include <cstring>
#include <thread>
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/File.h"
@@ -41,12 +36,13 @@
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/UriParser.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/ScopedPrinter.h"
-// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
@@ -222,8 +218,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
- const bool default_to_use_pty = true;
- m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
+ if (should_forward_stdio) {
+ if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection())
+ return Status(std::move(Err));
+ }
{
std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
@@ -1333,7 +1331,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
packet.SetFilePos(::strlen("QSetWorkingDir:"));
std::string path;
packet.GetHexByteString(path);
- m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
+ m_process_launch_info.SetWorkingDirectory(FileSpec(path));
return SendOKResponse();
}
@@ -3220,7 +3218,7 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
if (m_debugged_process_up
->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
.Success()) {
- if (file_spec.Exists())
+ if (FileSystem::Instance().Exists(file_spec))
return file_spec;
}
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 5a74d1acaa23..a085a3cc17dd 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -10,18 +10,14 @@
#ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_
#define liblldb_GDBRemoteCommunicationServerLLGS_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <unordered_map>
-// Other libraries and framework includes
#include "lldb/Core/Communication.h"
#include "lldb/Host/MainLoop.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/lldb-private-forward.h"
-// Project includes
#include "GDBRemoteCommunicationServerCommon.h"
class StringExtractorGDBRemote;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 26e28a900320..3521ddafbb16 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -11,15 +11,12 @@
#include <errno.h>
-// C Includes
-// C++ Includes
#include <chrono>
#include <csignal>
#include <cstring>
#include <mutex>
#include <sstream>
-// Other libraries and framework includes
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Threading.h"
@@ -38,7 +35,6 @@
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/UriParser.h"
-// Project includes
#include "lldb/Utility/StringExtractorGDBRemote.h"
using namespace lldb;
@@ -168,9 +164,6 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
StringExtractorGDBRemote &packet) {
-#ifdef _WIN32
- return SendErrorResponse(9);
-#else
// Spawn a local debugserver as a platform so we can then attach or launch a
// process...
@@ -221,10 +214,9 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
PacketResult packet_result = SendPacketNoLock(response.GetString());
if (packet_result != PacketResult::Success) {
if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
- ::kill(debugserver_pid, SIGINT);
+ Host::Kill(debugserver_pid, SIGINT);
}
return packet_result;
-#endif
}
GDBRemoteCommunication::PacketResult
@@ -532,7 +524,7 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
const char *domainsocket_dir_env =
::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
if (domainsocket_dir_env != nullptr)
- g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
+ g_domainsocket_dir = FileSpec(domainsocket_dir_env);
else
g_domainsocket_dir = HostInfo::GetProcessTempDir();
});
@@ -542,15 +534,15 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
FileSpec
GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
- llvm::SmallString<PATH_MAX> socket_path;
- llvm::SmallString<PATH_MAX> socket_name(
+ llvm::SmallString<128> socket_path;
+ llvm::SmallString<128> socket_name(
(llvm::StringRef(prefix) + ".%%%%%%").str());
FileSpec socket_path_spec(GetDomainSocketDir());
socket_path_spec.AppendPathComponent(socket_name.c_str());
llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
- return FileSpec(socket_path.c_str(), false);
+ return FileSpec(socket_path.c_str());
}
void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index aed5106272d1..df51e0367d1d 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -10,14 +10,10 @@
#ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_
#define liblldb_GDBRemoteCommunicationServerPlatform_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <set>
-// Other libraries and framework includes
-// Project includes
#include "GDBRemoteCommunicationServerCommon.h"
#include "lldb/Host/Socket.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 07dab751f4b9..e58f47f4befe 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -9,17 +9,13 @@
#include "GDBRemoteRegisterContext.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/StreamString.h"
-// Project includes
#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
@@ -462,7 +458,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues(
((ProcessGDBRemote *)process)->GetGDBRemote());
const bool use_g_packet =
- gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
+ !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
GDBRemoteClientBase::Lock lock(gdb_comm, false);
if (lock) {
@@ -525,7 +521,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues(
((ProcessGDBRemote *)process)->GetGDBRemote());
const bool use_g_packet =
- gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
+ !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process);
GDBRemoteClientBase::Lock lock(gdb_comm, false);
if (lock) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 8ef91af55e0f..6e8f3306669f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -10,12 +10,8 @@
#ifndef lldb_GDBRemoteRegisterContext_h_
#define lldb_GDBRemoteRegisterContext_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Utility/ConstString.h"
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index b3d33b19bd66..797f63d537a1 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -9,12 +9,11 @@
#include "lldb/Host/Config.h"
-// C Includes
#include <errno.h>
#include <stdlib.h>
#ifndef LLDB_DISABLE_POSIX
#include <netinet/in.h>
-#include <sys/mman.h> // for mmap
+#include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
@@ -22,7 +21,6 @@
#include <sys/types.h>
#include <time.h>
-// C++ Includes
#include <algorithm>
#include <csignal>
#include <map>
@@ -34,7 +32,6 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
#include "lldb/DataFormatters/FormatManager.h"
@@ -68,10 +65,11 @@
#include "lldb/Utility/Args.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
-// Project includes
#include "GDBRemoteRegisterContext.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
@@ -88,6 +86,7 @@
#include "llvm/Support/raw_ostream.h"
#define DEBUGSERVER_BASENAME "debugserver"
+using namespace llvm;
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
@@ -101,21 +100,21 @@ namespace lldb {
// and get the packet history dumped to a file.
void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
StreamFile strm;
- Status error(strm.GetFile().Open(path, File::eOpenOptionWrite |
- File::eOpenOptionCanCreate));
+ Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path),
+ File::eOpenOptionWrite |
+ File::eOpenOptionCanCreate);
if (error.Success())
((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
}
-}
+} // namespace lldb
namespace {
-static PropertyDefinition g_properties[] = {
- {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, NULL,
+static constexpr PropertyDefinition g_properties[] = {
+ {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, {},
"Specify the default packet timeout in seconds."},
- {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, NULL,
- "The file that provides the description for remote target registers."},
- {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
+ {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, {},
+ "The file that provides the description for remote target registers."}};
enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile };
@@ -158,7 +157,42 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
return g_settings_sp;
}
-} // anonymous namespace end
+class ProcessGDBRemoteProvider
+ : public repro::Provider<ProcessGDBRemoteProvider> {
+public:
+ ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) {
+ m_info.name = "gdb-remote";
+ m_info.files.push_back("gdb-remote.yaml");
+ }
+
+ raw_ostream *GetHistoryStream() {
+ FileSpec history_file =
+ GetRoot().CopyByAppendingPathComponent("gdb-remote.yaml");
+
+ std::error_code EC;
+ m_stream_up = llvm::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
+ sys::fs::OpenFlags::F_None);
+ return m_stream_up.get();
+ }
+
+ void SetCallback(std::function<void()> callback) {
+ m_callback = std::move(callback);
+ }
+
+ void Keep() override { m_callback(); }
+
+ void Discard() override { m_callback(); }
+
+ static char ID;
+
+private:
+ std::function<void()> m_callback;
+ std::unique_ptr<raw_fd_ostream> m_stream_up;
+};
+
+char ProcessGDBRemoteProvider::ID = 0;
+
+} // namespace
// TODO Randomly assigning a port is unsafe. We should get an unused
// ephemeral port from the kernel and make sure we reserve it before passing it
@@ -234,7 +268,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
case ObjectFile::eTypeUnknown:
break;
}
- return exe_module->GetFileSpec().Exists();
+ return FileSystem::Instance().Exists(exe_module->GetFileSpec());
}
// However, if there is no executable module, we return true since we might
// be preparing to attach.
@@ -259,8 +293,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_addr_to_mmap_size(), m_thread_create_bp_sp(),
m_waiting_for_attach(false), m_destroy_tried_resuming(false),
m_command_sp(), m_breakpoint_pc_offset(0),
- m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false),
- m_erased_flash_ranges() {
+ m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false),
+ m_allow_flash_writes(false), m_erased_flash_ranges() {
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
"async thread should exit");
m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
@@ -268,6 +302,15 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit,
"async thread did exit");
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ ProcessGDBRemoteProvider &provider =
+ g->GetOrCreate<ProcessGDBRemoteProvider>();
+ // Set the history stream to the stream owned by the provider.
+ m_gdb_comm.SetHistoryStream(provider.GetHistoryStream());
+ // Make sure to clear the stream again when we're finished.
+ provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); });
+ }
+
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
const uint32_t async_event_mask =
@@ -440,10 +483,10 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
FileSpec target_definition_fspec =
GetGlobalPluginProperties()->GetTargetDefinitionFile();
- if (!target_definition_fspec.Exists()) {
+ if (!FileSystem::Instance().Exists(target_definition_fspec)) {
// If the filename doesn't exist, it may be a ~ not having been expanded -
// try to resolve it.
- target_definition_fspec.ResolvePath();
+ FileSystem::Instance().Resolve(target_definition_fspec);
}
if (target_definition_fspec) {
// See if we can get register definitions from a python file
@@ -640,7 +683,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
m_register_info.Finalize(GetTarget().GetArchitecture());
}
-Status ProcessGDBRemote::WillLaunch(Module *module) {
+Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) {
return WillLaunchOrAttach();
}
@@ -689,7 +732,9 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm,
if (m_gdb_comm.GetProcessArchitecture().IsValid()) {
target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
} else {
- target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ if (m_gdb_comm.GetHostArchitecture().IsValid()) {
+ target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ }
}
}
@@ -754,7 +799,7 @@ Status ProcessGDBRemote::WillLaunchOrAttach() {
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
-Status ProcessGDBRemote::DoLaunch(Module *exe_module,
+Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module,
ProcessLaunchInfo &launch_info) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
Status error;
@@ -824,13 +869,13 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
if (disable_stdio) {
// set to /dev/null unless redirected to a file above
if (!stdin_file_spec)
- stdin_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ stdin_file_spec.SetFile(FileSystem::DEV_NULL,
FileSpec::Style::native);
if (!stdout_file_spec)
- stdout_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ stdout_file_spec.SetFile(FileSystem::DEV_NULL,
FileSpec::Style::native);
if (!stderr_file_spec)
- stderr_file_spec.SetFile(FileSystem::DEV_NULL, false,
+ stderr_file_spec.SetFile(FileSystem::DEV_NULL,
FileSpec::Style::native);
} else if (platform_sp && platform_sp->IsHost()) {
// If the debugserver is local and we aren't disabling STDIO, lets use
@@ -839,7 +884,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
// does a lot of output.
if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) {
- FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
+ FileSpec slave_name{pty.GetSlaveName(NULL, 0)};
if (!stdin_file_spec)
stdin_file_spec = slave_name;
@@ -1058,9 +1103,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
if (log)
log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, "
"using %s %s",
- __FUNCTION__, process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
process_arch.GetTriple().getTriple().c_str()
? process_arch.GetTriple().getTriple().c_str()
: "<null>");
@@ -1069,9 +1115,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
if (log)
log->Printf("ProcessGDBRemote::%s gdb-remote did not have process "
"architecture, using gdb-remote host architecture %s %s",
- __FUNCTION__, process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
process_arch.GetTriple().getTriple().c_str()
? process_arch.GetTriple().getTriple().c_str()
: "<null>");
@@ -1083,9 +1130,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
if (log)
log->Printf(
"ProcessGDBRemote::%s analyzing target arch, currently %s %s",
- __FUNCTION__, target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
+ __FUNCTION__,
+ target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
target_arch.GetTriple().getTriple().c_str()
? target_arch.GetTriple().getTriple().c_str()
: "<null>");
@@ -1105,9 +1153,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
if (log)
log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, "
"setting target arch to %s %s",
- __FUNCTION__, process_arch.GetArchitectureName()
- ? process_arch.GetArchitectureName()
- : "<null>",
+ __FUNCTION__,
+ process_arch.GetArchitectureName()
+ ? process_arch.GetArchitectureName()
+ : "<null>",
process_arch.GetTriple().getTriple().c_str()
? process_arch.GetTriple().getTriple().c_str()
: "<null>");
@@ -1135,9 +1184,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
if (log)
log->Printf("ProcessGDBRemote::%s final target arch after "
"adjustments for remote architecture: %s %s",
- __FUNCTION__, target_arch.GetArchitectureName()
- ? target_arch.GetArchitectureName()
- : "<null>",
+ __FUNCTION__,
+ target_arch.GetArchitectureName()
+ ? target_arch.GetArchitectureName()
+ : "<null>",
target_arch.GetTriple().getTriple().c_str()
? target_arch.GetTriple().getTriple().c_str()
: "<null>");
@@ -1478,7 +1528,7 @@ Status ProcessGDBRemote::DoResume() {
new EventDataBytes(continue_packet.GetString().data(),
continue_packet.GetSize()));
- if (listener_sp->GetEvent(event_sp, std::chrono::seconds(5)) == false) {
+ if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) {
error.SetErrorString("Resume timed out.");
if (log)
log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
@@ -1832,7 +1882,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
bool handled = false;
bool did_exec = false;
if (!reason.empty()) {
- if (reason.compare("trace") == 0) {
+ if (reason == "trace") {
addr_t pc = thread_sp->GetRegisterContext()->GetPC();
lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
->GetBreakpointSiteList()
@@ -1850,7 +1900,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonToTrace(*thread_sp));
handled = true;
- } else if (reason.compare("breakpoint") == 0) {
+ } else if (reason == "breakpoint") {
addr_t pc = thread_sp->GetRegisterContext()->GetPC();
lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
->GetBreakpointSiteList()
@@ -1871,9 +1921,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(invalid_stop_info_sp);
}
}
- } else if (reason.compare("trap") == 0) {
+ } else if (reason == "trap") {
// Let the trap just use the standard signal stop reason below...
- } else if (reason.compare("watchpoint") == 0) {
+ } else if (reason == "watchpoint") {
StringExtractor desc_extractor(description.c_str());
addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
@@ -1905,11 +1955,11 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
*thread_sp, watch_id, wp_hit_addr));
handled = true;
- } else if (reason.compare("exception") == 0) {
+ } else if (reason == "exception") {
thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
*thread_sp, description.c_str()));
handled = true;
- } else if (reason.compare("exec") == 0) {
+ } else if (reason == "exec") {
did_exec = true;
thread_sp->SetStopInfo(
StopInfo::CreateStopReasonWithExec(*thread_sp));
@@ -1934,7 +1984,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
}
}
- if (!handled && signo && did_exec == false) {
+ if (!handled && signo && !did_exec) {
if (signo == SIGTRAP) {
// Currently we are going to assume SIGTRAP means we are either
// hitting a breakpoint or hardware single stepping.
@@ -2648,7 +2698,7 @@ void ProcessGDBRemote::SetLastStopPacket(
// We are are not using non-stop mode, there can only be one last stop
// reply packet, so clear the list.
- if (GetTarget().GetNonStopModeEnabled() == false)
+ if (!GetTarget().GetNonStopModeEnabled())
m_stop_packet_stack.clear();
// Add this stop packet to the stop packet stack This stack will get popped
@@ -3378,6 +3428,43 @@ Status ProcessGDBRemote::DoSignal(int signo) {
return error;
}
+Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) {
+ if (!loader)
+ return Status("No loader provided.");
+
+ auto provider_info = loader->GetProviderInfo("gdb-remote");
+ if (!provider_info)
+ return Status("No provider for gdb-remote.");
+
+ if (provider_info->files.empty())
+ return Status("Provider for gdb-remote contains no files.");
+
+ // Construct replay history path.
+ FileSpec history_file = loader->GetRoot().CopyByAppendingPathComponent(
+ provider_info->files.front());
+
+ // Enable replay mode.
+ m_replay_mode = true;
+
+ // Load replay history.
+ if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file))
+ return Status("Unable to load replay history");
+
+ // Make a local connection.
+ if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm,
+ m_gdb_replay_server))
+ return Status("Unable to connect to replay server");
+
+ // Start server thread.
+ m_gdb_replay_server.StartAsyncThread();
+
+ // Start client thread.
+ StartAsyncThread();
+
+ // Do the usual setup.
+ return ConnectToDebugserver("");
+}
+
Status
ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
// Make sure we aren't already connected?
@@ -3388,6 +3475,9 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
if (platform_sp && !platform_sp->IsHost())
return Status("Lost debug server connection");
+ if (repro::Loader *loader = repro::Reproducer::Instance().GetLoader())
+ return ConnectToReplayServer(loader);
+
auto error = LaunchAndConnectToDebugserver(process_info);
if (error.Fail()) {
const char *error_string = error.AsCString();
@@ -3497,7 +3587,7 @@ bool ProcessGDBRemote::MonitorDebugserverProcess(
bool exited, // True if the process did exit
int signo, // Zero for no signal
int exit_status // Exit value of process if signal is zero
- ) {
+) {
// "debugserver_pid" argument passed in is the process ID for debugserver
// that we are tracking...
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
@@ -4269,8 +4359,9 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
return false;
feature_node.ForEachChildElementWithName(
- "reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
- &abi_sp](const XMLNode &reg_node) -> bool {
+ "reg",
+ [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
+ &abi_sp](const XMLNode &reg_node) -> bool {
std::string gdb_group;
std::string gdb_type;
ConstString reg_name;
@@ -4432,7 +4523,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
return true;
}
-} // namespace {}
+} // namespace
// query the target of gdb-remote for extended target information return:
// 'true' on success
@@ -4509,12 +4600,19 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
// <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board)
// use that if we don't have anything better.
if (!arch_to_use.IsValid() && !target_info.arch.empty()) {
- if (target_info.arch == "i386:x86-64")
- {
+ if (target_info.arch == "i386:x86-64") {
// We don't have any information about vendor or OS.
arch_to_use.SetTriple("x86_64--");
GetTarget().MergeArchitecture(arch_to_use);
}
+
+ // SEGGER J-Link jtag boards send this very-generic arch name,
+ // we'll need to use this if we have absolutely nothing better
+ // to work with or the register definitions won't be accepted.
+ if (target_info.arch == "arm") {
+ arch_to_use.SetTriple("arm--");
+ GetTarget().MergeArchitecture(arch_to_use);
+ }
}
// Initialize these outside of ParseRegisters, since they should not be
@@ -4760,7 +4858,8 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
if (!modInfo.get_link_map(link_map))
link_map = LLDB_INVALID_ADDRESS;
- FileSpec file(mod_name, true);
+ FileSpec file(mod_name);
+ FileSystem::Instance().Resolve(file);
lldb::ModuleSP module_sp =
LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset);
@@ -4802,7 +4901,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
return true;
lldb::ModuleSP module_copy_sp = module_sp;
- target.SetExecutableModule(module_copy_sp, false);
+ target.SetExecutableModule(module_copy_sp, eLoadDependentsNo);
return false;
});
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 45bb2d4c28e7..14a5237e4345 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -10,15 +10,12 @@
#ifndef liblldb_ProcessGDBRemote_h_
#define liblldb_ProcessGDBRemote_h_
-// C Includes
-// C++ Includes
#include <atomic>
#include <map>
#include <mutex>
#include <string>
#include <vector>
-#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ThreadSafeValue.h"
@@ -26,6 +23,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamGDBRemote.h"
@@ -36,11 +34,15 @@
#include "lldb/lldb-private-forward.h"
#include "GDBRemoteCommunicationClient.h"
+#include "GDBRemoteCommunicationReplayServer.h"
#include "GDBRemoteRegisterContext.h"
#include "llvm/ADT/DenseMap.h"
namespace lldb_private {
+namespace repro {
+class Loader;
+}
namespace process_gdb_remote {
class ThreadGDBRemote;
@@ -264,6 +266,7 @@ protected:
};
GDBRemoteCommunicationClient m_gdb_comm;
+ GDBRemoteCommunicationReplayServer m_gdb_replay_server;
std::atomic<lldb::pid_t> m_debugserver_pid;
std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
// stack replaces
@@ -304,6 +307,7 @@ protected:
int64_t m_breakpoint_pc_offset;
lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
+ bool m_replay_mode;
bool m_allow_flash_writes;
using FlashRangeVector = lldb_private::RangeVector<lldb::addr_t, size_t>;
using FlashRange = FlashRangeVector::Entry;
@@ -331,6 +335,8 @@ protected:
bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
+ Status ConnectToReplayServer(repro::Loader *loader);
+
Status EstablishConnectionIfNeeded(const ProcessInfo &process_info);
Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index 3c5801176690..d4981df88d8d 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -10,11 +10,7 @@
#ifndef liblldb_ProcessGDBRemoteLog_h_
#define liblldb_ProcessGDBRemoteLog_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/Log.h"
#define GDBR_LOG_PROCESS (1u << 1)
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index a525c16b9f13..db7dc3eae0ba 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/State.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -20,6 +19,7 @@
#include "lldb/Target/UnixSignals.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "ProcessGDBRemote.h"
@@ -197,13 +197,10 @@ void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(
}
bool ThreadGDBRemote::ThreadHasQueueInformation() const {
- if (m_thread_dispatch_qaddr != 0 &&
- m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&
- m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&
- m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0) {
- return true;
- }
- return false;
+ return m_thread_dispatch_qaddr != 0 &&
+ m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&
+ m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&
+ m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0;
}
LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index 1a5b60aea288..4485a9cdc4c3 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -10,12 +10,8 @@
#ifndef liblldb_ThreadGDBRemote_h_
#define liblldb_ThreadGDBRemote_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index bfa35ed506a9..08b9f08a47f6 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -8,38 +8,33 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <errno.h>
#include <stdlib.h>
-// C++ Includes
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Threading.h"
#include <mutex>
-// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
-// Project includes
#include "ProcessMachCore.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "ThreadMachCore.h"
// Needed for the plug-in names for the dynamic loaders.
-#include "lldb/Utility/SafeMachO.h"
+#include "lldb/Host/SafeMachO.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
@@ -67,8 +62,8 @@ lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
lldb::ProcessSP process_sp;
if (crash_file) {
const size_t header_size = sizeof(llvm::MachO::mach_header);
- auto data_sp =
- DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0);
+ auto data_sp = FileSystem::Instance().CreateDataBuffer(
+ crash_file->GetPath(), header_size, 0);
if (data_sp && data_sp->GetByteSize() == header_size) {
DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
@@ -90,7 +85,7 @@ bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
return true;
// For now we are just making sure the file exists for a given module
- if (!m_core_module_sp && m_core_file.Exists()) {
+ if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
// Don't add the Target's architecture to the ModuleSpec - we may be
// working with a core file that doesn't have the correct cpusubtype in the
// header but we should still try to use it -
@@ -307,36 +302,38 @@ Status ProcessMachCore::DoLoadCore() {
// LC_IDENT is very obsolete and should not be used in new code, but if the
// load command is present, let's use the contents.
std::string corefile_identifier = core_objfile->GetIdentifierString();
- if (found_main_binary_definitively == false
- && corefile_identifier.find("Darwin Kernel") != std::string::npos) {
- UUID uuid;
- addr_t addr = LLDB_INVALID_ADDRESS;
- if (corefile_identifier.find("UUID=") != std::string::npos) {
- size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
- std::string uuid_str = corefile_identifier.substr(p, 36);
- uuid.SetFromStringRef(uuid_str);
- }
- if (corefile_identifier.find("stext=") != std::string::npos) {
- size_t p = corefile_identifier.find("stext=") + strlen("stext=");
- if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
- errno = 0;
- addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16);
- if (errno != 0 || addr == 0)
- addr = LLDB_INVALID_ADDRESS;
- }
- }
- if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
- m_mach_kernel_addr = addr;
- found_main_binary_definitively = true;
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
- " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", addr, corefile_identifier.c_str());
+ if (!found_main_binary_definitively &&
+ corefile_identifier.find("Darwin Kernel") != std::string::npos) {
+ UUID uuid;
+ addr_t addr = LLDB_INVALID_ADDRESS;
+ if (corefile_identifier.find("UUID=") != std::string::npos) {
+ size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
+ std::string uuid_str = corefile_identifier.substr(p, 36);
+ uuid.SetFromStringRef(uuid_str);
+ }
+ if (corefile_identifier.find("stext=") != std::string::npos) {
+ size_t p = corefile_identifier.find("stext=") + strlen("stext=");
+ if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
+ errno = 0;
+ addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16);
+ if (errno != 0 || addr == 0)
+ addr = LLDB_INVALID_ADDRESS;
}
+ }
+ if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
+ m_mach_kernel_addr = addr;
+ found_main_binary_definitively = true;
+ if (log)
+ log->Printf(
+ "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
+ " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
+ addr, corefile_identifier.c_str());
+ }
}
- if (found_main_binary_definitively == false
- && (m_dyld_addr == LLDB_INVALID_ADDRESS
- || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
+ if (!found_main_binary_definitively &&
+ (m_dyld_addr == LLDB_INVALID_ADDRESS ||
+ m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
// We need to locate the main executable in the memory ranges we have in
// the core file. We need to search for both a user-process dyld binary
// and a kernel binary in memory; we must look at all the pages in the
@@ -357,16 +354,15 @@ Status ProcessMachCore::DoLoadCore() {
}
}
- if (found_main_binary_definitively == false
- && m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+ if (!found_main_binary_definitively &&
+ m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
// In the case of multiple kernel images found in the core file via
// exhaustive search, we may not pick the correct one. See if the
// DynamicLoaderDarwinKernel's search heuristics might identify the correct
// one. Most of the time, I expect the address from SearchForDarwinKernel()
// will be the same as the address we found via exhaustive search.
- if (GetTarget().GetArchitecture().IsValid() == false &&
- m_core_module_sp.get()) {
+ if (!GetTarget().GetArchitecture().IsValid() && m_core_module_sp.get()) {
GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
}
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
index 101df6b79115..0c6fc693a50c 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -10,13 +10,9 @@
#ifndef liblldb_ProcessMachCore_h_
#define liblldb_ProcessMachCore_h_
-// C Includes
-// C++ Includes
#include <list>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index c262dd47f978..16edd28f1a13 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -9,10 +9,7 @@
#include "ThreadMachCore.h"
-#include "lldb/Utility/SafeMachO.h"
-
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/State.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -21,6 +18,7 @@
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"
#include "ProcessMachCore.h"
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
index a4db484e850f..696ba7294e4a 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.h
@@ -10,12 +10,8 @@
#ifndef liblldb_ThreadMachCore_h_
#define liblldb_ThreadMachCore_h_
-// C Includes
-// C++ Includes
#include <string>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Target/Thread.h"
class ProcessMachCore;
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
index b898ee1aa144..4126a7ea991c 100644
--- a/source/Plugins/Process/minidump/CMakeLists.txt
+++ b/source/Plugins/Process/minidump/CMakeLists.txt
@@ -1,6 +1,8 @@
add_lldb_library(lldbPluginProcessMinidump PLUGIN
MinidumpTypes.cpp
MinidumpParser.cpp
+ RegisterContextMinidump_ARM.cpp
+ RegisterContextMinidump_ARM64.cpp
RegisterContextMinidump_x86_32.cpp
RegisterContextMinidump_x86_64.cpp
ProcessMinidump.cpp
diff --git a/source/Plugins/Process/minidump/MinidumpParser.cpp b/source/Plugins/Process/minidump/MinidumpParser.cpp
index 9a979335e99e..d4053ca70b94 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -7,20 +7,19 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "MinidumpParser.h"
#include "NtStructures.h"
#include "RegisterContextMinidump_x86_32.h"
-// Other libraries and framework includes
-#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "Plugins/Process/Utility/LinuxProcMaps.h"
// C includes
// C++ includes
#include <algorithm>
#include <map>
#include <vector>
+#include <utility>
using namespace lldb_private;
using namespace minidump;
@@ -80,8 +79,18 @@ UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) {
// PDB70 record
const CvRecordPdb70 *pdb70_uuid = nullptr;
Status error = consumeObject(cv_record, pdb70_uuid);
- if (!error.Fail())
- return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid));
+ if (!error.Fail()) {
+ auto arch = GetArchitecture();
+ // For Apple targets we only need a 16 byte UUID so that we can match
+ // the UUID in the Module to actual UUIDs from the built binaries. The
+ // "Age" field is zero in breakpad minidump files for Apple targets, so
+ // we restrict the UUID to the "Uuid" field so we have a UUID we can use
+ // to match.
+ if (arch.GetTriple().getVendor() == llvm::Triple::Apple)
+ return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
+ else
+ return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid));
+ }
} else if (cv_signature == CvSignature::ElfBuildId)
return UUID::fromData(cv_record);
@@ -98,11 +107,15 @@ llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
}
llvm::ArrayRef<uint8_t>
-MinidumpParser::GetThreadContext(const MinidumpThread &td) {
- if (td.thread_context.rva + td.thread_context.data_size > GetData().size())
+MinidumpParser::GetThreadContext(const MinidumpLocationDescriptor &location) {
+ if (location.rva + location.data_size > GetData().size())
return {};
+ return GetData().slice(location.rva, location.data_size);
+}
- return GetData().slice(td.thread_context.rva, td.thread_context.data_size);
+llvm::ArrayRef<uint8_t>
+MinidumpParser::GetThreadContext(const MinidumpThread &td) {
+ return GetThreadContext(td.thread_context);
}
llvm::ArrayRef<uint8_t>
@@ -146,11 +159,14 @@ const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() {
}
ArchSpec MinidumpParser::GetArchitecture() {
- ArchSpec arch_spec;
+ if (m_arch.IsValid())
+ return m_arch;
+
+ // Set the architecture in m_arch
const MinidumpSystemInfo *system_info = GetSystemInfo();
if (!system_info)
- return arch_spec;
+ return m_arch;
// TODO what to do about big endiand flavors of arm ?
// TODO set the arm subarch stuff if the minidump has info about it
@@ -196,19 +212,28 @@ ArchSpec MinidumpParser::GetArchitecture() {
break;
case MinidumpOSPlatform::MacOSX:
triple.setOS(llvm::Triple::OSType::MacOSX);
+ triple.setVendor(llvm::Triple::Apple);
+ break;
+ case MinidumpOSPlatform::IOS:
+ triple.setOS(llvm::Triple::OSType::IOS);
+ triple.setVendor(llvm::Triple::Apple);
break;
case MinidumpOSPlatform::Android:
triple.setOS(llvm::Triple::OSType::Linux);
triple.setEnvironment(llvm::Triple::EnvironmentType::Android);
break;
- default:
+ default: {
triple.setOS(llvm::Triple::OSType::UnknownOS);
+ std::string csd_version;
+ if (auto s = GetMinidumpString(system_info->csd_version_rva))
+ csd_version = *s;
+ if (csd_version.find("Linux") != std::string::npos)
+ triple.setOS(llvm::Triple::OSType::Linux);
break;
+ }
}
-
- arch_spec.SetTriple(triple);
-
- return arch_spec;
+ m_arch.SetTriple(triple);
+ return m_arch;
}
const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() {
@@ -254,36 +279,45 @@ llvm::ArrayRef<MinidumpModule> MinidumpParser::GetModuleList() {
std::vector<const MinidumpModule *> MinidumpParser::GetFilteredModuleList() {
llvm::ArrayRef<MinidumpModule> modules = GetModuleList();
- // map module_name -> pair(load_address, pointer to module struct in memory)
- llvm::StringMap<std::pair<uint64_t, const MinidumpModule *>> lowest_addr;
+ // map module_name -> filtered_modules index
+ typedef llvm::StringMap<size_t> MapType;
+ MapType module_name_to_filtered_index;
std::vector<const MinidumpModule *> filtered_modules;
-
+
llvm::Optional<std::string> name;
std::string module_name;
for (const auto &module : modules) {
name = GetMinidumpString(module.module_name_rva);
-
+
if (!name)
continue;
-
+
module_name = name.getValue();
-
- auto iter = lowest_addr.end();
- bool exists;
- std::tie(iter, exists) = lowest_addr.try_emplace(
- module_name, std::make_pair(module.base_of_image, &module));
-
- if (exists && module.base_of_image < iter->second.first)
- iter->second = std::make_pair(module.base_of_image, &module);
- }
-
- filtered_modules.reserve(lowest_addr.size());
- for (const auto &module : lowest_addr) {
- filtered_modules.push_back(module.second.second);
+
+ MapType::iterator iter;
+ bool inserted;
+ // See if we have inserted this module aready into filtered_modules. If we
+ // haven't insert an entry into module_name_to_filtered_index with the
+ // index where we will insert it if it isn't in the vector already.
+ std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace(
+ module_name, filtered_modules.size());
+
+ if (inserted) {
+ // This module has not been seen yet, insert it into filtered_modules at
+ // the index that was inserted into module_name_to_filtered_index using
+ // "filtered_modules.size()" above.
+ filtered_modules.push_back(&module);
+ } else {
+ // This module has been seen. Modules are sometimes mentioned multiple
+ // times when they are mapped discontiguously, so find the module with
+ // the lowest "base_of_image" and use that as the filtered module.
+ auto dup_module = filtered_modules[iter->second];
+ if (module.base_of_image < dup_module->base_of_image)
+ filtered_modules[iter->second] = &module;
+ }
}
-
return filtered_modules;
}
@@ -381,72 +415,153 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
return range->range_ref.slice(offset, overlap);
}
-llvm::Optional<MemoryRegionInfo>
-MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
- MemoryRegionInfo info;
- llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryInfoList);
+static bool
+CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser,
+ std::vector<MemoryRegionInfo> &regions) {
+ auto data = parser.GetStream(MinidumpStreamType::LinuxMaps);
if (data.empty())
- return llvm::None;
+ return false;
+ ParseLinuxMapRegions(llvm::toStringRef(data),
+ [&](const lldb_private::MemoryRegionInfo &region,
+ const lldb_private::Status &status) -> bool {
+ if (status.Success())
+ regions.push_back(region);
+ return true;
+ });
+ return !regions.empty();
+}
- std::vector<const MinidumpMemoryInfo *> mem_info_list =
- MinidumpMemoryInfo::ParseMemoryInfoList(data);
+static bool
+CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser,
+ std::vector<MemoryRegionInfo> &regions) {
+ auto data = parser.GetStream(MinidumpStreamType::MemoryInfoList);
+ if (data.empty())
+ return false;
+ auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data);
if (mem_info_list.empty())
- return llvm::None;
+ return false;
+ constexpr auto yes = MemoryRegionInfo::eYes;
+ constexpr auto no = MemoryRegionInfo::eNo;
+ regions.reserve(mem_info_list.size());
+ for (const auto &entry : mem_info_list) {
+ MemoryRegionInfo region;
+ region.GetRange().SetRangeBase(entry->base_address);
+ region.GetRange().SetByteSize(entry->region_size);
+ region.SetReadable(entry->isReadable() ? yes : no);
+ region.SetWritable(entry->isWritable() ? yes : no);
+ region.SetExecutable(entry->isExecutable() ? yes : no);
+ region.SetMapped(entry->isMapped() ? yes : no);
+ regions.push_back(region);
+ }
+ return !regions.empty();
+}
- const auto yes = MemoryRegionInfo::eYes;
- const auto no = MemoryRegionInfo::eNo;
+static bool
+CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
+ std::vector<MemoryRegionInfo> &regions) {
+ auto data = parser.GetStream(MinidumpStreamType::MemoryList);
+ if (data.empty())
+ return false;
+ auto memory_list = MinidumpMemoryDescriptor::ParseMemoryList(data);
+ if (memory_list.empty())
+ return false;
+ regions.reserve(memory_list.size());
+ for (const auto &memory_desc : memory_list) {
+ if (memory_desc.memory.data_size == 0)
+ continue;
+ MemoryRegionInfo region;
+ region.GetRange().SetRangeBase(memory_desc.start_of_memory_range);
+ region.GetRange().SetByteSize(memory_desc.memory.data_size);
+ region.SetReadable(MemoryRegionInfo::eYes);
+ region.SetMapped(MemoryRegionInfo::eYes);
+ regions.push_back(region);
+ }
+ regions.shrink_to_fit();
+ return !regions.empty();
+}
- const MinidumpMemoryInfo *next_entry = nullptr;
- for (const auto &entry : mem_info_list) {
- const auto head = entry->base_address;
- const auto tail = head + entry->region_size;
-
- if (head <= load_addr && load_addr < tail) {
- info.GetRange().SetRangeBase(
- (entry->state != uint32_t(MinidumpMemoryInfoState::MemFree))
- ? head
- : load_addr);
- info.GetRange().SetRangeEnd(tail);
-
- const uint32_t PageNoAccess =
- static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageNoAccess);
- info.SetReadable((entry->protect & PageNoAccess) == 0 ? yes : no);
-
- const uint32_t PageWritable =
- static_cast<uint32_t>(MinidumpMemoryProtectionContants::PageWritable);
- info.SetWritable((entry->protect & PageWritable) != 0 ? yes : no);
-
- const uint32_t PageExecutable = static_cast<uint32_t>(
- MinidumpMemoryProtectionContants::PageExecutable);
- info.SetExecutable((entry->protect & PageExecutable) != 0 ? yes : no);
-
- const uint32_t MemFree =
- static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree);
- info.SetMapped((entry->state != MemFree) ? yes : no);
-
- return info;
- } else if (head > load_addr &&
- (next_entry == nullptr || head < next_entry->base_address)) {
- // In case there is no region containing load_addr keep track of the
- // nearest region after load_addr so we can return the distance to it.
- next_entry = entry;
- }
+static bool
+CreateRegionsCacheFromMemory64List(MinidumpParser &parser,
+ std::vector<MemoryRegionInfo> &regions) {
+ llvm::ArrayRef<uint8_t> data =
+ parser.GetStream(MinidumpStreamType::Memory64List);
+ if (data.empty())
+ return false;
+ llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
+ uint64_t base_rva;
+ std::tie(memory64_list, base_rva) =
+ MinidumpMemoryDescriptor64::ParseMemory64List(data);
+
+ if (memory64_list.empty())
+ return false;
+
+ regions.reserve(memory64_list.size());
+ for (const auto &memory_desc : memory64_list) {
+ if (memory_desc.data_size == 0)
+ continue;
+ MemoryRegionInfo region;
+ region.GetRange().SetRangeBase(memory_desc.start_of_memory_range);
+ region.GetRange().SetByteSize(memory_desc.data_size);
+ region.SetReadable(MemoryRegionInfo::eYes);
+ region.SetMapped(MemoryRegionInfo::eYes);
+ regions.push_back(region);
}
+ regions.shrink_to_fit();
+ return !regions.empty();
+}
+
+MemoryRegionInfo
+MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const {
+ auto begin = m_regions.begin();
+ auto end = m_regions.end();
+ auto pos = std::lower_bound(begin, end, load_addr);
+ if (pos != end && pos->GetRange().Contains(load_addr))
+ return *pos;
+
+ MemoryRegionInfo region;
+ if (pos == begin)
+ region.GetRange().SetRangeBase(0);
+ else {
+ auto prev = pos - 1;
+ if (prev->GetRange().Contains(load_addr))
+ return *prev;
+ region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd());
+ }
+ if (pos == end)
+ region.GetRange().SetRangeEnd(UINT64_MAX);
+ else
+ region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
+ region.SetReadable(MemoryRegionInfo::eNo);
+ region.SetWritable(MemoryRegionInfo::eNo);
+ region.SetExecutable(MemoryRegionInfo::eNo);
+ region.SetMapped(MemoryRegionInfo::eNo);
+ return region;
+}
- // No containing region found. Create an unmapped region that extends to the
- // next region or LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(load_addr);
- info.GetRange().SetRangeEnd((next_entry != nullptr) ? next_entry->base_address
- : LLDB_INVALID_ADDRESS);
- info.SetReadable(no);
- info.SetWritable(no);
- info.SetExecutable(no);
- info.SetMapped(no);
-
- // Note that the memory info list doesn't seem to contain ranges in kernel
- // space, so if you're walking a stack that has kernel frames, the stack may
- // appear truncated.
- return info;
+MemoryRegionInfo
+MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
+ if (!m_parsed_regions)
+ GetMemoryRegions();
+ return FindMemoryRegion(load_addr);
+}
+
+const MemoryRegionInfos &MinidumpParser::GetMemoryRegions() {
+ if (!m_parsed_regions) {
+ m_parsed_regions = true;
+ // We haven't cached our memory regions yet we will create the region cache
+ // once. We create the region cache using the best source. We start with
+ // the linux maps since they are the most complete and have names for the
+ // regions. Next we try the MemoryInfoList since it has
+ // read/write/execute/map data, and then fall back to the MemoryList and
+ // Memory64List to just get a list of the memory that is mapped in this
+ // core file
+ if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions))
+ if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions))
+ if (!CreateRegionsCacheFromMemoryList(*this, m_regions))
+ CreateRegionsCacheFromMemory64List(*this, m_regions);
+ llvm::sort(m_regions.begin(), m_regions.end());
+ }
+ return m_regions;
}
Status MinidumpParser::Initialize() {
@@ -531,10 +646,10 @@ Status MinidumpParser::Initialize() {
}
// Sort the file map ranges by start offset
- std::sort(minidump_map.begin(), minidump_map.end(),
- [](const FileRange &a, const FileRange &b) {
- return a.offset < b.offset;
- });
+ llvm::sort(minidump_map.begin(), minidump_map.end(),
+ [](const FileRange &a, const FileRange &b) {
+ return a.offset < b.offset;
+ });
// Check for overlapping streams/data structures
for (size_t i = 1; i < minidump_map.size(); ++i) {
@@ -554,3 +669,48 @@ Status MinidumpParser::Initialize() {
return error;
}
+
+#define ENUM_TO_CSTR(ST) case (uint32_t)MinidumpStreamType::ST: return #ST
+
+llvm::StringRef
+MinidumpParser::GetStreamTypeAsString(uint32_t stream_type) {
+ switch (stream_type) {
+ ENUM_TO_CSTR(Unused);
+ ENUM_TO_CSTR(Reserved0);
+ ENUM_TO_CSTR(Reserved1);
+ ENUM_TO_CSTR(ThreadList);
+ ENUM_TO_CSTR(ModuleList);
+ ENUM_TO_CSTR(MemoryList);
+ ENUM_TO_CSTR(Exception);
+ ENUM_TO_CSTR(SystemInfo);
+ ENUM_TO_CSTR(ThreadExList);
+ ENUM_TO_CSTR(Memory64List);
+ ENUM_TO_CSTR(CommentA);
+ ENUM_TO_CSTR(CommentW);
+ ENUM_TO_CSTR(HandleData);
+ ENUM_TO_CSTR(FunctionTable);
+ ENUM_TO_CSTR(UnloadedModuleList);
+ ENUM_TO_CSTR(MiscInfo);
+ ENUM_TO_CSTR(MemoryInfoList);
+ ENUM_TO_CSTR(ThreadInfoList);
+ ENUM_TO_CSTR(HandleOperationList);
+ ENUM_TO_CSTR(Token);
+ ENUM_TO_CSTR(JavascriptData);
+ ENUM_TO_CSTR(SystemMemoryInfo);
+ ENUM_TO_CSTR(ProcessVMCounters);
+ ENUM_TO_CSTR(BreakpadInfo);
+ ENUM_TO_CSTR(AssertionInfo);
+ ENUM_TO_CSTR(LinuxCPUInfo);
+ ENUM_TO_CSTR(LinuxProcStatus);
+ ENUM_TO_CSTR(LinuxLSBRelease);
+ ENUM_TO_CSTR(LinuxCMDLine);
+ ENUM_TO_CSTR(LinuxEnviron);
+ ENUM_TO_CSTR(LinuxAuxv);
+ ENUM_TO_CSTR(LinuxMaps);
+ ENUM_TO_CSTR(LinuxDSODebug);
+ ENUM_TO_CSTR(LinuxProcStat);
+ ENUM_TO_CSTR(LinuxProcUptime);
+ ENUM_TO_CSTR(LinuxProcFD);
+ }
+ return "unknown stream type";
+}
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index 49b1eef14de5..07ea6aa908ff 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -1,5 +1,4 @@
-//===-- MinidumpParser.h -----------------------------------------*- C++
-//-*-===//
+//===-- MinidumpParser.h -----------------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,9 +10,9 @@
#ifndef liblldb_MinidumpParser_h_
#define liblldb_MinidumpParser_h_
-// Project includes
#include "MinidumpTypes.h"
+#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
@@ -59,6 +58,9 @@ public:
llvm::ArrayRef<MinidumpThread> GetThreads();
+ llvm::ArrayRef<uint8_t>
+ GetThreadContext(const MinidumpLocationDescriptor &location);
+
llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td);
llvm::ArrayRef<uint8_t> GetThreadContextWow64(const MinidumpThread &td);
@@ -87,17 +89,31 @@ public:
llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
- llvm::Optional<MemoryRegionInfo> GetMemoryRegionInfo(lldb::addr_t);
+ MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr);
+
+ const MemoryRegionInfos &GetMemoryRegions();
// Perform consistency checks and initialize internal data structures
Status Initialize();
+ static llvm::StringRef GetStreamTypeAsString(uint32_t stream_type);
+
+ const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &
+ GetDirectoryMap() const {
+ return m_directory_map;
+ }
+
private:
MinidumpParser(const lldb::DataBufferSP &data_buf_sp);
+ MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const;
+
private:
lldb::DataBufferSP m_data_sp;
llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> m_directory_map;
+ ArchSpec m_arch;
+ MemoryRegionInfos m_regions;
+ bool m_parsed_regions = false;
};
} // end namespace minidump
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.cpp b/source/Plugins/Process/minidump/MinidumpTypes.cpp
index 049704ba80ca..7b1900e34ef1 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ b/source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -7,10 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
// C includes
// C++ includes
@@ -244,6 +242,8 @@ MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data) {
return {};
std::vector<const MinidumpMemoryInfo *> result;
+ result.reserve(header->num_of_entries);
+
for (uint64_t i = 0; i < header->num_of_entries; ++i) {
result.push_back(reinterpret_cast<const MinidumpMemoryInfo *>(
data.data() + i * header->size_of_entry));
diff --git a/source/Plugins/Process/minidump/MinidumpTypes.h b/source/Plugins/Process/minidump/MinidumpTypes.h
index e83089865b9e..a5ea215d2548 100644
--- a/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -10,9 +10,7 @@
#ifndef liblldb_MinidumpTypes_h_
#define liblldb_MinidumpTypes_h_
-// Project includes
-// Other libraries and framework includes
#include "lldb/Utility/Status.h"
#include "llvm/ADT/ArrayRef.h"
@@ -98,7 +96,10 @@ enum class MinidumpStreamType : uint32_t {
LinuxEnviron = 0x47670007, /* /proc/$x/environ */
LinuxAuxv = 0x47670008, /* /proc/$x/auxv */
LinuxMaps = 0x47670009, /* /proc/$x/maps */
- LinuxDSODebug = 0x4767000A
+ LinuxDSODebug = 0x4767000A,
+ LinuxProcStat = 0x4767000B, /* /proc/$x/stat */
+ LinuxProcUptime = 0x4767000C, /* uptime */
+ LinuxProcFD = 0x4767000D, /* /proc/$x/fb */
};
// for MinidumpSystemInfo.processor_arch
@@ -258,25 +259,6 @@ struct MinidumpMemoryInfoListHeader {
static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16,
"sizeof MinidumpMemoryInfoListHeader is not correct!");
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
-struct MinidumpMemoryInfo {
- llvm::support::ulittle64_t base_address;
- llvm::support::ulittle64_t allocation_base;
- llvm::support::ulittle32_t allocation_protect;
- llvm::support::ulittle32_t alignment1;
- llvm::support::ulittle64_t region_size;
- llvm::support::ulittle32_t state;
- llvm::support::ulittle32_t protect;
- llvm::support::ulittle32_t type;
- llvm::support::ulittle32_t alignment2;
-
- static std::vector<const MinidumpMemoryInfo *>
- ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
-};
-static_assert(sizeof(MinidumpMemoryInfo) == 48,
- "sizeof MinidumpMemoryInfo is not correct!");
-
enum class MinidumpMemoryInfoState : uint32_t {
MemCommit = 0x1000,
MemFree = 0x10000,
@@ -313,6 +295,45 @@ enum class MinidumpMemoryProtectionContants : uint32_t {
};
// Reference:
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx
+struct MinidumpMemoryInfo {
+ llvm::support::ulittle64_t base_address;
+ llvm::support::ulittle64_t allocation_base;
+ llvm::support::ulittle32_t allocation_protect;
+ llvm::support::ulittle32_t alignment1;
+ llvm::support::ulittle64_t region_size;
+ llvm::support::ulittle32_t state;
+ llvm::support::ulittle32_t protect;
+ llvm::support::ulittle32_t type;
+ llvm::support::ulittle32_t alignment2;
+
+ static std::vector<const MinidumpMemoryInfo *>
+ ParseMemoryInfoList(llvm::ArrayRef<uint8_t> &data);
+
+ bool isReadable() const {
+ const auto mask = MinidumpMemoryProtectionContants::PageNoAccess;
+ return (static_cast<uint32_t>(mask) & protect) == 0;
+ }
+
+ bool isWritable() const {
+ const auto mask = MinidumpMemoryProtectionContants::PageWritable;
+ return (static_cast<uint32_t>(mask) & protect) != 0;
+ }
+
+ bool isExecutable() const {
+ const auto mask = MinidumpMemoryProtectionContants::PageExecutable;
+ return (static_cast<uint32_t>(mask) & protect) != 0;
+ }
+
+ bool isMapped() const {
+ return state != static_cast<uint32_t>(MinidumpMemoryInfoState::MemFree);
+ }
+};
+
+static_assert(sizeof(MinidumpMemoryInfo) == 48,
+ "sizeof MinidumpMemoryInfo is not correct!");
+
+// Reference:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
struct MinidumpThread {
llvm::support::ulittle32_t thread_id;
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.cpp b/source/Plugins/Process/minidump/ProcessMinidump.cpp
index b43f22382eac..c5cca7ea62c6 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -7,28 +7,34 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "ProcessMinidump.h"
#include "ThreadMinidump.h"
-// Other libraries and framework includes
+#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Core/State.h"
-#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionArgParser.h"
+#include "lldb/Interpreter/OptionGroupBoolean.h"
+#include "lldb/Target/JITLoaderList.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Threading.h"
+#include "Plugins/Process/Utility/StopInfoMachException.h"
+
// C includes
// C++ includes
@@ -75,7 +81,7 @@ public:
section_sp, module->base_of_image);
}
- ObjectFile *GetObjectFile() override { return nullptr; }
+ObjectFile *GetObjectFile() override { return nullptr; }
SectionList *GetSectionList() override {
return Module::GetUnifiedSectionList();
@@ -100,8 +106,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
lldb::ProcessSP process_sp;
// Read enough data for the Minidump header
constexpr size_t header_size = sizeof(MinidumpHeader);
- auto DataPtr =
- DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0);
+ auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(),
+ header_size, 0);
if (!DataPtr)
return nullptr;
@@ -113,7 +119,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
if (header == nullptr)
return nullptr;
- auto AllData = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), -1, 0);
+ auto AllData =
+ FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0);
if (!AllData)
return nullptr;
@@ -174,19 +181,21 @@ Status ProcessMinidump::DoLoadCore() {
switch (arch.GetMachine()) {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- // supported
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ // Any supported architectures must be listed here and also supported in
+ // ThreadMinidump::CreateRegisterContextForFrame().
break;
-
default:
error.SetErrorStringWithFormat("unsupported minidump architecture: %s",
arch.GetArchitectureName());
return error;
}
+ GetTarget().SetArchitecture(arch, true /*set_platform*/);
m_thread_list = m_minidump_parser.GetThreads();
m_active_exception = m_minidump_parser.GetExceptionStream();
ReadModuleList();
- GetTarget().SetArchitecture(arch);
llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid();
if (!pid) {
@@ -198,12 +207,6 @@ Status ProcessMinidump::DoLoadCore() {
return error;
}
-DynamicLoader *ProcessMinidump::GetDynamicLoader() {
- if (m_dyld_ap.get() == nullptr)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
- return m_dyld_ap.get();
-}
-
ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ProcessMinidump::GetPluginVersion() { return 1; }
@@ -229,6 +232,11 @@ void ProcessMinidump::RefreshStateAfterStop() {
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
stop_info = StopInfo::CreateStopReasonWithSignal(
*stop_thread, m_active_exception->exception_record.exception_code);
+ } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) {
+ stop_info = StopInfoMachException::CreateStopReasonWithMachException(
+ *stop_thread, m_active_exception->exception_record.exception_code, 2,
+ m_active_exception->exception_record.exception_flags,
+ m_active_exception->exception_record.exception_address, 0);
} else {
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
@@ -284,33 +292,36 @@ ArchSpec ProcessMinidump::GetArchitecture() {
Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) {
- Status error;
- auto info = m_minidump_parser.GetMemoryRegionInfo(load_addr);
- if (!info) {
- error.SetErrorString("No valid MemoryRegionInfo found!");
- return error;
- }
- range_info = info.getValue();
- return error;
+ range_info = m_minidump_parser.GetMemoryRegionInfo(load_addr);
+ return Status();
+}
+
+Status ProcessMinidump::GetMemoryRegions(
+ lldb_private::MemoryRegionInfos &region_list) {
+ region_list = m_minidump_parser.GetMemoryRegions();
+ return Status();
}
void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); }
bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) {
- uint32_t num_threads = 0;
- if (m_thread_list.size() > 0)
- num_threads = m_thread_list.size();
+ for (const MinidumpThread& thread : m_thread_list) {
+ MinidumpLocationDescriptor context_location = thread.thread_context;
+
+ // If the minidump contains an exception context, use it
+ if (m_active_exception != nullptr &&
+ m_active_exception->thread_id == thread.thread_id) {
+ context_location = m_active_exception->thread_context;
+ }
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
llvm::ArrayRef<uint8_t> context;
if (!m_is_wow64)
- context = m_minidump_parser.GetThreadContext(m_thread_list[tid]);
+ context = m_minidump_parser.GetThreadContext(context_location);
else
- context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]);
+ context = m_minidump_parser.GetThreadContextWow64(thread);
- lldb::ThreadSP thread_sp(
- new ThreadMinidump(*this, m_thread_list[tid], context));
+ lldb::ThreadSP thread_sp(new ThreadMinidump(*this, thread, context));
new_thread_list.AddThread(thread_sp);
}
return new_thread_list.GetSize(false) > 0;
@@ -344,8 +355,8 @@ void ProcessMinidump::ReadModuleList() {
}
const auto uuid = m_minidump_parser.GetModuleUUID(module);
- const auto file_spec =
- FileSpec(name.getValue(), true, GetArchitecture().GetTriple());
+ auto file_spec = FileSpec(name.getValue(), GetArchitecture().GetTriple());
+ FileSystem::Instance().Resolve(file_spec);
ModuleSpec module_spec(file_spec, uuid);
Status error;
lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error);
@@ -357,6 +368,12 @@ void ProcessMinidump::ReadModuleList() {
// This enables most LLDB functionality involving address-to-module
// translations (ex. identifing the module for a stack frame PC) and
// modules/sections commands (ex. target modules list, ...)
+ if (log) {
+ log->Printf("Unable to locate the matching object file, creating a "
+ "placeholder module for: %s",
+ name.getValue().c_str());
+ }
+
auto placeholder_module =
std::make_shared<PlaceholderModule>(module_spec);
placeholder_module->CreateImageSection(module, GetTarget());
@@ -387,3 +404,248 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) {
}
return true;
}
+
+// For minidumps there's no runtime generated code so we don't need JITLoader(s)
+// Avoiding them will also speed up minidump loading since JITLoaders normally
+// try to set up symbolic breakpoints, which in turn may force loading more
+// debug information than needed.
+JITLoaderList &ProcessMinidump::GetJITLoaders() {
+ if (!m_jit_loaders_ap) {
+ m_jit_loaders_ap = llvm::make_unique<JITLoaderList>();
+ }
+ return *m_jit_loaders_ap;
+}
+
+#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
+ VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
+#define APPEND_OPT(VAR) \
+ m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
+
+class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
+private:
+ OptionGroupOptions m_option_group;
+ OptionGroupBoolean m_dump_all;
+ OptionGroupBoolean m_dump_directory;
+ OptionGroupBoolean m_dump_linux_cpuinfo;
+ OptionGroupBoolean m_dump_linux_proc_status;
+ OptionGroupBoolean m_dump_linux_lsb_release;
+ OptionGroupBoolean m_dump_linux_cmdline;
+ OptionGroupBoolean m_dump_linux_environ;
+ OptionGroupBoolean m_dump_linux_auxv;
+ OptionGroupBoolean m_dump_linux_maps;
+ OptionGroupBoolean m_dump_linux_proc_stat;
+ OptionGroupBoolean m_dump_linux_proc_uptime;
+ OptionGroupBoolean m_dump_linux_proc_fd;
+ OptionGroupBoolean m_dump_linux_all;
+
+ void SetDefaultOptionsIfNoneAreSet() {
+ if (m_dump_all.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_all.GetOptionValue().GetCurrentValue() ||
+ m_dump_directory.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_proc_status.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_cmdline.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_environ.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_auxv.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_maps.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue() ||
+ m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue())
+ return;
+ // If no options were set, then dump everything
+ m_dump_all.GetOptionValue().SetCurrentValue(true);
+ }
+ bool DumpAll() const {
+ return m_dump_all.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpDirectory() const {
+ return DumpAll() ||
+ m_dump_directory.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinux() const {
+ return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxCPUInfo() const {
+ return DumpLinux() ||
+ m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxProcStatus() const {
+ return DumpLinux() ||
+ m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxProcStat() const {
+ return DumpLinux() ||
+ m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxLSBRelease() const {
+ return DumpLinux() ||
+ m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxCMDLine() const {
+ return DumpLinux() ||
+ m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxEnviron() const {
+ return DumpLinux() ||
+ m_dump_linux_environ.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxAuxv() const {
+ return DumpLinux() ||
+ m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxMaps() const {
+ return DumpLinux() ||
+ m_dump_linux_maps.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxProcUptime() const {
+ return DumpLinux() ||
+ m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
+ }
+ bool DumpLinuxProcFD() const {
+ return DumpLinux() ||
+ m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
+ }
+public:
+
+ CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "process plugin dump",
+ "Dump information from the minidump file.", NULL),
+ m_option_group(),
+ INIT_BOOL(m_dump_all, "all", 'a',
+ "Dump the everything in the minidump."),
+ INIT_BOOL(m_dump_directory, "directory", 'd',
+ "Dump the minidump directory map."),
+ INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
+ "Dump linux /proc/cpuinfo."),
+ INIT_BOOL(m_dump_linux_proc_status, "status", 's',
+ "Dump linux /proc/<pid>/status."),
+ INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
+ "Dump linux /etc/lsb-release."),
+ INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
+ "Dump linux /proc/<pid>/cmdline."),
+ INIT_BOOL(m_dump_linux_environ, "environ", 'e',
+ "Dump linux /proc/<pid>/environ."),
+ INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
+ "Dump linux /proc/<pid>/auxv."),
+ INIT_BOOL(m_dump_linux_maps, "maps", 'm',
+ "Dump linux /proc/<pid>/maps."),
+ INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
+ "Dump linux /proc/<pid>/stat."),
+ INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
+ "Dump linux process uptime."),
+ INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
+ "Dump linux /proc/<pid>/fd."),
+ INIT_BOOL(m_dump_linux_all, "linux", 'l',
+ "Dump all linux streams.") {
+ APPEND_OPT(m_dump_all);
+ APPEND_OPT(m_dump_directory);
+ APPEND_OPT(m_dump_linux_cpuinfo);
+ APPEND_OPT(m_dump_linux_proc_status);
+ APPEND_OPT(m_dump_linux_lsb_release);
+ APPEND_OPT(m_dump_linux_cmdline);
+ APPEND_OPT(m_dump_linux_environ);
+ APPEND_OPT(m_dump_linux_auxv);
+ APPEND_OPT(m_dump_linux_maps);
+ APPEND_OPT(m_dump_linux_proc_stat);
+ APPEND_OPT(m_dump_linux_proc_uptime);
+ APPEND_OPT(m_dump_linux_proc_fd);
+ APPEND_OPT(m_dump_linux_all);
+ m_option_group.Finalize();
+ }
+
+ ~CommandObjectProcessMinidumpDump() {}
+
+ Options *GetOptions() override { return &m_option_group; }
+
+ bool DoExecute(Args &command, CommandReturnObject &result) override {
+ const size_t argc = command.GetArgumentCount();
+ if (argc > 0) {
+ result.AppendErrorWithFormat("'%s' take no arguments, only options",
+ m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ SetDefaultOptionsIfNoneAreSet();
+
+ ProcessMinidump *process = static_cast<ProcessMinidump *>(
+ m_interpreter.GetExecutionContext().GetProcessPtr());
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ Stream &s = result.GetOutputStream();
+ MinidumpParser &minidump = process->m_minidump_parser;
+ if (DumpDirectory()) {
+ s.Printf("RVA SIZE TYPE MinidumpStreamType\n");
+ s.Printf("---------- ---------- ---------- --------------------------\n");
+ for (const auto &pair: minidump.GetDirectoryMap())
+ s.Printf("0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)pair.second.rva,
+ (uint32_t)pair.second.data_size, pair.first,
+ MinidumpParser::GetStreamTypeAsString(pair.first).data());
+ s.Printf("\n");
+ }
+ auto DumpTextStream = [&](MinidumpStreamType stream_type,
+ llvm::StringRef label) -> void {
+ auto bytes = minidump.GetStream(stream_type);
+ if (!bytes.empty()) {
+ if (label.empty())
+ label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type);
+ s.Printf("%s:\n%s\n\n", label.data(), bytes.data());
+ }
+ };
+ auto DumpBinaryStream = [&](MinidumpStreamType stream_type,
+ llvm::StringRef label) -> void {
+ auto bytes = minidump.GetStream(stream_type);
+ if (!bytes.empty()) {
+ if (label.empty())
+ label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type);
+ s.Printf("%s:\n", label.data());
+ DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
+ process->GetAddressByteSize());
+ DumpDataExtractor(data, &s, 0, lldb::eFormatBytesWithASCII, 1,
+ bytes.size(), 16, 0, 0, 0);
+ s.Printf("\n\n");
+ }
+ };
+
+ if (DumpLinuxCPUInfo())
+ DumpTextStream(MinidumpStreamType::LinuxCPUInfo, "/proc/cpuinfo");
+ if (DumpLinuxProcStatus())
+ DumpTextStream(MinidumpStreamType::LinuxProcStatus, "/proc/PID/status");
+ if (DumpLinuxLSBRelease())
+ DumpTextStream(MinidumpStreamType::LinuxLSBRelease, "/etc/lsb-release");
+ if (DumpLinuxCMDLine())
+ DumpTextStream(MinidumpStreamType::LinuxCMDLine, "/proc/PID/cmdline");
+ if (DumpLinuxEnviron())
+ DumpTextStream(MinidumpStreamType::LinuxEnviron, "/proc/PID/environ");
+ if (DumpLinuxAuxv())
+ DumpBinaryStream(MinidumpStreamType::LinuxAuxv, "/proc/PID/auxv");
+ if (DumpLinuxMaps())
+ DumpTextStream(MinidumpStreamType::LinuxMaps, "/proc/PID/maps");
+ if (DumpLinuxProcStat())
+ DumpTextStream(MinidumpStreamType::LinuxProcStat, "/proc/PID/stat");
+ if (DumpLinuxProcUptime())
+ DumpTextStream(MinidumpStreamType::LinuxProcUptime, "uptime");
+ if (DumpLinuxProcFD())
+ DumpTextStream(MinidumpStreamType::LinuxProcFD, "/proc/PID/fd");
+ return true;
+ }
+};
+
+class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
+public:
+ CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "process plugin",
+ "Commands for operating on a ProcessMinidump process.",
+ "process plugin <subcommand> [<subcommand-options>]") {
+ LoadSubCommand("dump",
+ CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
+ }
+
+ ~CommandObjectMultiwordProcessMinidump() {}
+};
+
+CommandObject *ProcessMinidump::GetPluginCommandObject() {
+ if (!m_command_sp)
+ m_command_sp.reset(new CommandObjectMultiwordProcessMinidump(
+ GetTarget().GetDebugger().GetCommandInterpreter()));
+ return m_command_sp.get();
+}
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index d65ada9009a7..30347b79e1c1 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -10,11 +10,9 @@
#ifndef liblldb_ProcessMinidump_h_
#define liblldb_ProcessMinidump_h_
-// Project includes
#include "MinidumpParser.h"
#include "MinidumpTypes.h"
-// Other libraries and framework includes
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
@@ -24,8 +22,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-// C Includes
-// C++ Includes
namespace lldb_private {
@@ -53,9 +49,11 @@ public:
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
+ CommandObject *GetPluginCommandObject() override;
+
Status DoLoadCore() override;
- DynamicLoader *GetDynamicLoader() override;
+ DynamicLoader *GetDynamicLoader() override { return nullptr; }
ConstString GetPluginName() override;
@@ -82,6 +80,9 @@ public:
Status GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) override;
+ Status GetMemoryRegions(
+ lldb_private::MemoryRegionInfos &region_list) override;
+
bool GetProcessInfo(ProcessInstanceInfo &info) override;
Status WillResume() override {
@@ -102,10 +103,13 @@ protected:
void ReadModuleList();
+ JITLoaderList &GetJITLoaders() override;
+
private:
FileSpec m_core_file;
llvm::ArrayRef<MinidumpThread> m_thread_list;
const MinidumpExceptionStream *m_active_exception;
+ lldb::CommandObjectSP m_command_sp;
bool m_is_wow64;
};
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
new file mode 100644
index 000000000000..93c3ba70b9e7
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp
@@ -0,0 +1,532 @@
+//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextMinidump_ARM.h"
+
+#include "Utility/ARM_DWARF_Registers.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-enumerations.h"
+
+// C includes
+#include <assert.h>
+
+// C++ includes
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace minidump;
+
+#define INV LLDB_INVALID_REGNUM
+#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r))
+
+#define DEF_R(i) \
+ { \
+ "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
+ {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_R_ARG(i, n) \
+ { \
+ "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \
+ {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_D(i) \
+ { \
+ "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, dwarf_d##i, INV, INV, reg_d##i}, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_S(i) \
+ { \
+ "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \
+ {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_Q(i) \
+ { \
+ "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, dwarf_q##i, INV, INV, reg_q##i}, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+// Zero based LLDB register numbers for this register context
+enum {
+ // General Purpose Registers
+ reg_r0,
+ reg_r1,
+ reg_r2,
+ reg_r3,
+ reg_r4,
+ reg_r5,
+ reg_r6,
+ reg_r7,
+ reg_r8,
+ reg_r9,
+ reg_r10,
+ reg_r11,
+ reg_r12,
+ reg_sp,
+ reg_lr,
+ reg_pc,
+ reg_cpsr,
+ // Floating Point Registers
+ reg_fpscr,
+ reg_d0,
+ reg_d1,
+ reg_d2,
+ reg_d3,
+ reg_d4,
+ reg_d5,
+ reg_d6,
+ reg_d7,
+ reg_d8,
+ reg_d9,
+ reg_d10,
+ reg_d11,
+ reg_d12,
+ reg_d13,
+ reg_d14,
+ reg_d15,
+ reg_d16,
+ reg_d17,
+ reg_d18,
+ reg_d19,
+ reg_d20,
+ reg_d21,
+ reg_d22,
+ reg_d23,
+ reg_d24,
+ reg_d25,
+ reg_d26,
+ reg_d27,
+ reg_d28,
+ reg_d29,
+ reg_d30,
+ reg_d31,
+ reg_s0,
+ reg_s1,
+ reg_s2,
+ reg_s3,
+ reg_s4,
+ reg_s5,
+ reg_s6,
+ reg_s7,
+ reg_s8,
+ reg_s9,
+ reg_s10,
+ reg_s11,
+ reg_s12,
+ reg_s13,
+ reg_s14,
+ reg_s15,
+ reg_s16,
+ reg_s17,
+ reg_s18,
+ reg_s19,
+ reg_s20,
+ reg_s21,
+ reg_s22,
+ reg_s23,
+ reg_s24,
+ reg_s25,
+ reg_s26,
+ reg_s27,
+ reg_s28,
+ reg_s29,
+ reg_s30,
+ reg_s31,
+ reg_q0,
+ reg_q1,
+ reg_q2,
+ reg_q3,
+ reg_q4,
+ reg_q5,
+ reg_q6,
+ reg_q7,
+ reg_q8,
+ reg_q9,
+ reg_q10,
+ reg_q11,
+ reg_q12,
+ reg_q13,
+ reg_q14,
+ reg_q15,
+ k_num_regs
+};
+
+static RegisterInfo g_reg_info_apple_fp = {
+ "fp",
+ "r7",
+ 4,
+ OFFSET(r) + 7 * 4,
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+
+static RegisterInfo g_reg_info_fp = {
+ "fp",
+ "r11",
+ 4,
+ OFFSET(r) + 11 * 4,
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0};
+
+// Register info definitions for this register context
+static RegisterInfo g_reg_infos[] = {
+ DEF_R_ARG(0, 1),
+ DEF_R_ARG(1, 2),
+ DEF_R_ARG(2, 3),
+ DEF_R_ARG(3, 4),
+ DEF_R(4),
+ DEF_R(5),
+ DEF_R(6),
+ DEF_R(7),
+ DEF_R(8),
+ DEF_R(9),
+ DEF_R(10),
+ DEF_R(11),
+ DEF_R(12),
+ {"sp",
+ "r13",
+ 4,
+ OFFSET(r) + 13 * 4,
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "r14",
+ 4,
+ OFFSET(r) + 14 * 4,
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ "r15",
+ 4,
+ OFFSET(r) + 15 * 4,
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"cpsr",
+ "psr",
+ 4,
+ OFFSET(cpsr),
+ eEncodingUint,
+ eFormatHex,
+ {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpscr",
+ nullptr,
+ 8,
+ OFFSET(fpscr),
+ eEncodingUint,
+ eFormatHex,
+ {INV, INV, INV, INV, reg_fpscr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ DEF_D(0),
+ DEF_D(1),
+ DEF_D(2),
+ DEF_D(3),
+ DEF_D(4),
+ DEF_D(5),
+ DEF_D(6),
+ DEF_D(7),
+ DEF_D(8),
+ DEF_D(9),
+ DEF_D(10),
+ DEF_D(11),
+ DEF_D(12),
+ DEF_D(13),
+ DEF_D(14),
+ DEF_D(15),
+ DEF_D(16),
+ DEF_D(17),
+ DEF_D(18),
+ DEF_D(19),
+ DEF_D(20),
+ DEF_D(21),
+ DEF_D(22),
+ DEF_D(23),
+ DEF_D(24),
+ DEF_D(25),
+ DEF_D(26),
+ DEF_D(27),
+ DEF_D(28),
+ DEF_D(29),
+ DEF_D(30),
+ DEF_D(31),
+ DEF_S(0),
+ DEF_S(1),
+ DEF_S(2),
+ DEF_S(3),
+ DEF_S(4),
+ DEF_S(5),
+ DEF_S(6),
+ DEF_S(7),
+ DEF_S(8),
+ DEF_S(9),
+ DEF_S(10),
+ DEF_S(11),
+ DEF_S(12),
+ DEF_S(13),
+ DEF_S(14),
+ DEF_S(15),
+ DEF_S(16),
+ DEF_S(17),
+ DEF_S(18),
+ DEF_S(19),
+ DEF_S(20),
+ DEF_S(21),
+ DEF_S(22),
+ DEF_S(23),
+ DEF_S(24),
+ DEF_S(25),
+ DEF_S(26),
+ DEF_S(27),
+ DEF_S(28),
+ DEF_S(29),
+ DEF_S(30),
+ DEF_S(31),
+ DEF_Q(0),
+ DEF_Q(1),
+ DEF_Q(2),
+ DEF_Q(3),
+ DEF_Q(4),
+ DEF_Q(5),
+ DEF_Q(6),
+ DEF_Q(7),
+ DEF_Q(8),
+ DEF_Q(9),
+ DEF_Q(10),
+ DEF_Q(11),
+ DEF_Q(12),
+ DEF_Q(13),
+ DEF_Q(14),
+ DEF_Q(15)};
+
+constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos);
+
+// ARM general purpose registers.
+const uint32_t g_gpr_regnums[] = {
+ reg_r0,
+ reg_r1,
+ reg_r2,
+ reg_r3,
+ reg_r4,
+ reg_r5,
+ reg_r6,
+ reg_r7,
+ reg_r8,
+ reg_r9,
+ reg_r10,
+ reg_r11,
+ reg_r12,
+ reg_sp,
+ reg_lr,
+ reg_pc,
+ reg_cpsr,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+const uint32_t g_fpu_regnums[] = {
+ reg_fpscr,
+ reg_d0,
+ reg_d1,
+ reg_d2,
+ reg_d3,
+ reg_d4,
+ reg_d5,
+ reg_d6,
+ reg_d7,
+ reg_d8,
+ reg_d9,
+ reg_d10,
+ reg_d11,
+ reg_d12,
+ reg_d13,
+ reg_d14,
+ reg_d15,
+ reg_d16,
+ reg_d17,
+ reg_d18,
+ reg_d19,
+ reg_d20,
+ reg_d21,
+ reg_d22,
+ reg_d23,
+ reg_d24,
+ reg_d25,
+ reg_d26,
+ reg_d27,
+ reg_d28,
+ reg_d29,
+ reg_d30,
+ reg_d31,
+ reg_s0,
+ reg_s1,
+ reg_s2,
+ reg_s3,
+ reg_s4,
+ reg_s5,
+ reg_s6,
+ reg_s7,
+ reg_s8,
+ reg_s9,
+ reg_s10,
+ reg_s11,
+ reg_s12,
+ reg_s13,
+ reg_s14,
+ reg_s15,
+ reg_s16,
+ reg_s17,
+ reg_s18,
+ reg_s19,
+ reg_s20,
+ reg_s21,
+ reg_s22,
+ reg_s23,
+ reg_s24,
+ reg_s25,
+ reg_s26,
+ reg_s27,
+ reg_s28,
+ reg_s29,
+ reg_s30,
+ reg_s31,
+ reg_q0,
+ reg_q1,
+ reg_q2,
+ reg_q3,
+ reg_q4,
+ reg_q5,
+ reg_q6,
+ reg_q7,
+ reg_q8,
+ reg_q9,
+ reg_q10,
+ reg_q11,
+ reg_q12,
+ reg_q13,
+ reg_q14,
+ reg_q15,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1
+constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1;
+constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1;
+
+static RegisterSet g_reg_sets[] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums},
+ {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums},
+};
+
+constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets);
+
+RegisterContextMinidump_ARM::RegisterContextMinidump_ARM(
+ Thread &thread, const DataExtractor &data, bool apple)
+ : RegisterContext(thread, 0), m_apple(apple) {
+ lldb::offset_t offset = 0;
+ m_regs.context_flags = data.GetU32(&offset);
+ for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i)
+ m_regs.r[i] = data.GetU32(&offset);
+ m_regs.cpsr = data.GetU32(&offset);
+ m_regs.fpscr = data.GetU64(&offset);
+ for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i)
+ m_regs.d[i] = data.GetU64(&offset);
+ lldbassert(k_num_regs == k_num_reg_infos);
+}
+
+size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; }
+
+const RegisterInfo *
+RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_reg_infos) {
+ if (m_apple) {
+ if (reg == reg_r7)
+ return &g_reg_info_apple_fp;
+ } else {
+ if (reg == reg_r11)
+ return &g_reg_info_fp;
+ }
+ return &g_reg_infos[reg];
+ }
+ return nullptr;
+}
+
+size_t RegisterContextMinidump_ARM::GetRegisterSetCount() {
+ return k_num_reg_sets;
+}
+
+const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) {
+ if (set < k_num_reg_sets)
+ return &g_reg_sets[set];
+ return nullptr;
+}
+
+const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) {
+ if (reg < k_num_reg_infos)
+ return g_reg_infos[reg].name;
+ return nullptr;
+}
+
+bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+ reg_value.SetFromMemoryData(
+ reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
+ return error.Success();
+}
+
+bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *,
+ const RegisterValue &) {
+ return false;
+}
+
+uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ for (size_t i = 0; i < k_num_regs; ++i) {
+ if (g_reg_infos[i].kinds[kind] == num)
+ return i;
+ }
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
new file mode 100644
index 000000000000..959611a1491d
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h
@@ -0,0 +1,93 @@
+//===-- RegisterContextMinidump_ARM.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_RegisterContextMinidump_ARM_h_
+#define liblldb_RegisterContextMinidump_ARM_h_
+
+#include "MinidumpTypes.h"
+
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
+
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+class RegisterContextMinidump_ARM : public lldb_private::RegisterContext {
+public:
+ RegisterContextMinidump_ARM(lldb_private::Thread &thread,
+ const DataExtractor &data, bool apple);
+
+ ~RegisterContextMinidump_ARM() override = default;
+
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
+
+ size_t GetRegisterCount() override;
+
+ 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);
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ // Reference: see breakpad/crashpad source
+ struct QRegValue {
+ uint64_t lo;
+ uint64_t hi;
+ };
+
+ struct Context {
+ uint32_t context_flags;
+ uint32_t r[16];
+ uint32_t cpsr;
+ uint64_t fpscr;
+ union {
+ uint64_t d[32];
+ uint32_t s[32];
+ QRegValue q[16];
+ };
+ uint32_t extra[8];
+ };
+
+protected:
+ enum class Flags : uint32_t {
+ ARM_Flag = 0x40000000,
+ Integer = ARM_Flag | 0x00000002,
+ FloatingPoint = ARM_Flag | 0x00000004,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint)
+ };
+ Context m_regs;
+ const bool m_apple; // True if this is an Apple ARM where FP is R7
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_ARM_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
new file mode 100644
index 000000000000..3582e7d01867
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp
@@ -0,0 +1,834 @@
+//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextMinidump_ARM64.h"
+
+#include "Utility/ARM64_DWARF_Registers.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/lldb-enumerations.h"
+
+// C includes
+#include <assert.h>
+
+// C++ includes
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace minidump;
+
+#define INV LLDB_INVALID_REGNUM
+#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r))
+
+#define DEF_X(i) \
+ { \
+ "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \
+ {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \
+ nullptr, 0 \
+ }
+
+#define DEF_W(i) \
+ { \
+ "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \
+ {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_X_ARG(i, n) \
+ { \
+ "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \
+ {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_V(i) \
+ { \
+ "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \
+ nullptr, nullptr, nullptr, 0 \
+ }
+
+#define DEF_D(i) \
+ { \
+ "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \
+ nullptr, nullptr, 0 \
+ }
+
+#define DEF_S(i) \
+ { \
+ "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \
+ nullptr, nullptr, 0 \
+ }
+
+#define DEF_H(i) \
+ { \
+ "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \
+ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \
+ nullptr, nullptr, 0 \
+ }
+
+// Zero based LLDB register numbers for this register context
+enum {
+ // General Purpose Registers
+ reg_x0 = 0,
+ reg_x1,
+ reg_x2,
+ reg_x3,
+ reg_x4,
+ reg_x5,
+ reg_x6,
+ reg_x7,
+ reg_x8,
+ reg_x9,
+ reg_x10,
+ reg_x11,
+ reg_x12,
+ reg_x13,
+ reg_x14,
+ reg_x15,
+ reg_x16,
+ reg_x17,
+ reg_x18,
+ reg_x19,
+ reg_x20,
+ reg_x21,
+ reg_x22,
+ reg_x23,
+ reg_x24,
+ reg_x25,
+ reg_x26,
+ reg_x27,
+ reg_x28,
+ reg_fp,
+ reg_lr,
+ reg_sp,
+ reg_pc,
+ reg_w0,
+ reg_w1,
+ reg_w2,
+ reg_w3,
+ reg_w4,
+ reg_w5,
+ reg_w6,
+ reg_w7,
+ reg_w8,
+ reg_w9,
+ reg_w10,
+ reg_w11,
+ reg_w12,
+ reg_w13,
+ reg_w14,
+ reg_w15,
+ reg_w16,
+ reg_w17,
+ reg_w18,
+ reg_w19,
+ reg_w20,
+ reg_w21,
+ reg_w22,
+ reg_w23,
+ reg_w24,
+ reg_w25,
+ reg_w26,
+ reg_w27,
+ reg_w28,
+ reg_w29,
+ reg_w30,
+ reg_w31,
+ reg_cpsr,
+ // Floating Point Registers
+ reg_fpsr,
+ reg_fpcr,
+ reg_v0,
+ reg_v1,
+ reg_v2,
+ reg_v3,
+ reg_v4,
+ reg_v5,
+ reg_v6,
+ reg_v7,
+ reg_v8,
+ reg_v9,
+ reg_v10,
+ reg_v11,
+ reg_v12,
+ reg_v13,
+ reg_v14,
+ reg_v15,
+ reg_v16,
+ reg_v17,
+ reg_v18,
+ reg_v19,
+ reg_v20,
+ reg_v21,
+ reg_v22,
+ reg_v23,
+ reg_v24,
+ reg_v25,
+ reg_v26,
+ reg_v27,
+ reg_v28,
+ reg_v29,
+ reg_v30,
+ reg_v31,
+ reg_d0,
+ reg_d1,
+ reg_d2,
+ reg_d3,
+ reg_d4,
+ reg_d5,
+ reg_d6,
+ reg_d7,
+ reg_d8,
+ reg_d9,
+ reg_d10,
+ reg_d11,
+ reg_d12,
+ reg_d13,
+ reg_d14,
+ reg_d15,
+ reg_d16,
+ reg_d17,
+ reg_d18,
+ reg_d19,
+ reg_d20,
+ reg_d21,
+ reg_d22,
+ reg_d23,
+ reg_d24,
+ reg_d25,
+ reg_d26,
+ reg_d27,
+ reg_d28,
+ reg_d29,
+ reg_d30,
+ reg_d31,
+ reg_s0,
+ reg_s1,
+ reg_s2,
+ reg_s3,
+ reg_s4,
+ reg_s5,
+ reg_s6,
+ reg_s7,
+ reg_s8,
+ reg_s9,
+ reg_s10,
+ reg_s11,
+ reg_s12,
+ reg_s13,
+ reg_s14,
+ reg_s15,
+ reg_s16,
+ reg_s17,
+ reg_s18,
+ reg_s19,
+ reg_s20,
+ reg_s21,
+ reg_s22,
+ reg_s23,
+ reg_s24,
+ reg_s25,
+ reg_s26,
+ reg_s27,
+ reg_s28,
+ reg_s29,
+ reg_s30,
+ reg_s31,
+ reg_h0,
+ reg_h1,
+ reg_h2,
+ reg_h3,
+ reg_h4,
+ reg_h5,
+ reg_h6,
+ reg_h7,
+ reg_h8,
+ reg_h9,
+ reg_h10,
+ reg_h11,
+ reg_h12,
+ reg_h13,
+ reg_h14,
+ reg_h15,
+ reg_h16,
+ reg_h17,
+ reg_h18,
+ reg_h19,
+ reg_h20,
+ reg_h21,
+ reg_h22,
+ reg_h23,
+ reg_h24,
+ reg_h25,
+ reg_h26,
+ reg_h27,
+ reg_h28,
+ reg_h29,
+ reg_h30,
+ reg_h31,
+ k_num_regs
+};
+
+// Register info definitions for this register context
+static RegisterInfo g_reg_infos[] = {
+ DEF_X_ARG(0, 1),
+ DEF_X_ARG(1, 2),
+ DEF_X_ARG(2, 3),
+ DEF_X_ARG(3, 4),
+ DEF_X_ARG(4, 5),
+ DEF_X_ARG(5, 6),
+ DEF_X_ARG(6, 7),
+ DEF_X_ARG(7, 8),
+ DEF_X(8),
+ DEF_X(9),
+ DEF_X(10),
+ DEF_X(11),
+ DEF_X(12),
+ DEF_X(13),
+ DEF_X(14),
+ DEF_X(15),
+ DEF_X(16),
+ DEF_X(17),
+ DEF_X(18),
+ DEF_X(19),
+ DEF_X(20),
+ DEF_X(21),
+ DEF_X(22),
+ DEF_X(23),
+ DEF_X(24),
+ DEF_X(25),
+ DEF_X(26),
+ DEF_X(27),
+ DEF_X(28),
+ {"fp",
+ "x29",
+ 8,
+ OFFSET(x) + 29 * 8,
+ eEncodingUint,
+ eFormatHex,
+ {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"lr",
+ "x30",
+ 8,
+ OFFSET(x) + 30 * 8,
+ eEncodingUint,
+ eFormatHex,
+ {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"sp",
+ "x31",
+ 8,
+ OFFSET(x) + 31 * 8,
+ eEncodingUint,
+ eFormatHex,
+ {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"pc",
+ nullptr,
+ 8,
+ OFFSET(pc),
+ eEncodingUint,
+ eFormatHex,
+ {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // w0 - w31
+ DEF_W(0),
+ DEF_W(1),
+ DEF_W(2),
+ DEF_W(3),
+ DEF_W(4),
+ DEF_W(5),
+ DEF_W(6),
+ DEF_W(7),
+ DEF_W(8),
+ DEF_W(9),
+ DEF_W(10),
+ DEF_W(11),
+ DEF_W(12),
+ DEF_W(13),
+ DEF_W(14),
+ DEF_W(15),
+ DEF_W(16),
+ DEF_W(17),
+ DEF_W(18),
+ DEF_W(19),
+ DEF_W(20),
+ DEF_W(21),
+ DEF_W(22),
+ DEF_W(23),
+ DEF_W(24),
+ DEF_W(25),
+ DEF_W(26),
+ DEF_W(27),
+ DEF_W(28),
+ DEF_W(29),
+ DEF_W(30),
+ DEF_W(31),
+ {"cpsr",
+ "psr",
+ 4,
+ OFFSET(cpsr),
+ eEncodingUint,
+ eFormatHex,
+ {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpsr",
+ nullptr,
+ 4,
+ OFFSET(fpsr),
+ eEncodingUint,
+ eFormatHex,
+ {INV, INV, INV, INV, reg_fpsr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ {"fpcr",
+ nullptr,
+ 4,
+ OFFSET(fpcr),
+ eEncodingUint,
+ eFormatHex,
+ {INV, INV, INV, INV, reg_fpcr},
+ nullptr,
+ nullptr,
+ nullptr,
+ 0},
+ // v0 - v31
+ DEF_V(0),
+ DEF_V(1),
+ DEF_V(2),
+ DEF_V(3),
+ DEF_V(4),
+ DEF_V(5),
+ DEF_V(6),
+ DEF_V(7),
+ DEF_V(8),
+ DEF_V(9),
+ DEF_V(10),
+ DEF_V(11),
+ DEF_V(12),
+ DEF_V(13),
+ DEF_V(14),
+ DEF_V(15),
+ DEF_V(16),
+ DEF_V(17),
+ DEF_V(18),
+ DEF_V(19),
+ DEF_V(20),
+ DEF_V(21),
+ DEF_V(22),
+ DEF_V(23),
+ DEF_V(24),
+ DEF_V(25),
+ DEF_V(26),
+ DEF_V(27),
+ DEF_V(28),
+ DEF_V(29),
+ DEF_V(30),
+ DEF_V(31),
+ // d0 - d31
+ DEF_D(0),
+ DEF_D(1),
+ DEF_D(2),
+ DEF_D(3),
+ DEF_D(4),
+ DEF_D(5),
+ DEF_D(6),
+ DEF_D(7),
+ DEF_D(8),
+ DEF_D(9),
+ DEF_D(10),
+ DEF_D(11),
+ DEF_D(12),
+ DEF_D(13),
+ DEF_D(14),
+ DEF_D(15),
+ DEF_D(16),
+ DEF_D(17),
+ DEF_D(18),
+ DEF_D(19),
+ DEF_D(20),
+ DEF_D(21),
+ DEF_D(22),
+ DEF_D(23),
+ DEF_D(24),
+ DEF_D(25),
+ DEF_D(26),
+ DEF_D(27),
+ DEF_D(28),
+ DEF_D(29),
+ DEF_D(30),
+ DEF_D(31),
+ // s0 - s31
+ DEF_S(0),
+ DEF_S(1),
+ DEF_S(2),
+ DEF_S(3),
+ DEF_S(4),
+ DEF_S(5),
+ DEF_S(6),
+ DEF_S(7),
+ DEF_S(8),
+ DEF_S(9),
+ DEF_S(10),
+ DEF_S(11),
+ DEF_S(12),
+ DEF_S(13),
+ DEF_S(14),
+ DEF_S(15),
+ DEF_S(16),
+ DEF_S(17),
+ DEF_S(18),
+ DEF_S(19),
+ DEF_S(20),
+ DEF_S(21),
+ DEF_S(22),
+ DEF_S(23),
+ DEF_S(24),
+ DEF_S(25),
+ DEF_S(26),
+ DEF_S(27),
+ DEF_S(28),
+ DEF_S(29),
+ DEF_S(30),
+ DEF_S(31),
+ // h0 - h31
+ DEF_H(0),
+ DEF_H(1),
+ DEF_H(2),
+ DEF_H(3),
+ DEF_H(4),
+ DEF_H(5),
+ DEF_H(6),
+ DEF_H(7),
+ DEF_H(8),
+ DEF_H(9),
+ DEF_H(10),
+ DEF_H(11),
+ DEF_H(12),
+ DEF_H(13),
+ DEF_H(14),
+ DEF_H(15),
+ DEF_H(16),
+ DEF_H(17),
+ DEF_H(18),
+ DEF_H(19),
+ DEF_H(20),
+ DEF_H(21),
+ DEF_H(22),
+ DEF_H(23),
+ DEF_H(24),
+ DEF_H(25),
+ DEF_H(26),
+ DEF_H(27),
+ DEF_H(28),
+ DEF_H(29),
+ DEF_H(30),
+ DEF_H(31),
+};
+
+constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos);
+
+// ARM64 general purpose registers.
+const uint32_t g_gpr_regnums[] = {
+ reg_x0,
+ reg_x1,
+ reg_x2,
+ reg_x3,
+ reg_x4,
+ reg_x5,
+ reg_x6,
+ reg_x7,
+ reg_x8,
+ reg_x9,
+ reg_x10,
+ reg_x11,
+ reg_x12,
+ reg_x13,
+ reg_x14,
+ reg_x15,
+ reg_x16,
+ reg_x17,
+ reg_x18,
+ reg_x19,
+ reg_x20,
+ reg_x21,
+ reg_x22,
+ reg_x23,
+ reg_x24,
+ reg_x25,
+ reg_x26,
+ reg_x27,
+ reg_x28,
+ reg_fp,
+ reg_lr,
+ reg_sp,
+ reg_w0,
+ reg_w1,
+ reg_w2,
+ reg_w3,
+ reg_w4,
+ reg_w5,
+ reg_w6,
+ reg_w7,
+ reg_w8,
+ reg_w9,
+ reg_w10,
+ reg_w11,
+ reg_w12,
+ reg_w13,
+ reg_w14,
+ reg_w15,
+ reg_w16,
+ reg_w17,
+ reg_w18,
+ reg_w19,
+ reg_w20,
+ reg_w21,
+ reg_w22,
+ reg_w23,
+ reg_w24,
+ reg_w25,
+ reg_w26,
+ reg_w27,
+ reg_w28,
+ reg_w29,
+ reg_w30,
+ reg_w31,
+ reg_pc,
+ reg_cpsr,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+const uint32_t g_fpu_regnums[] = {
+ reg_v0,
+ reg_v1,
+ reg_v2,
+ reg_v3,
+ reg_v4,
+ reg_v5,
+ reg_v6,
+ reg_v7,
+ reg_v8,
+ reg_v9,
+ reg_v10,
+ reg_v11,
+ reg_v12,
+ reg_v13,
+ reg_v14,
+ reg_v15,
+ reg_v16,
+ reg_v17,
+ reg_v18,
+ reg_v19,
+ reg_v20,
+ reg_v21,
+ reg_v22,
+ reg_v23,
+ reg_v24,
+ reg_v25,
+ reg_v26,
+ reg_v27,
+ reg_v28,
+ reg_v29,
+ reg_v30,
+ reg_v31,
+ reg_d0,
+ reg_d1,
+ reg_d2,
+ reg_d3,
+ reg_d4,
+ reg_d5,
+ reg_d6,
+ reg_d7,
+ reg_d8,
+ reg_d9,
+ reg_d10,
+ reg_d11,
+ reg_d12,
+ reg_d13,
+ reg_d14,
+ reg_d15,
+ reg_d16,
+ reg_d17,
+ reg_d18,
+ reg_d19,
+ reg_d20,
+ reg_d21,
+ reg_d22,
+ reg_d23,
+ reg_d24,
+ reg_d25,
+ reg_d26,
+ reg_d27,
+ reg_d28,
+ reg_d29,
+ reg_d30,
+ reg_d31,
+ reg_s0,
+ reg_s1,
+ reg_s2,
+ reg_s3,
+ reg_s4,
+ reg_s5,
+ reg_s6,
+ reg_s7,
+ reg_s8,
+ reg_s9,
+ reg_s10,
+ reg_s11,
+ reg_s12,
+ reg_s13,
+ reg_s14,
+ reg_s15,
+ reg_s16,
+ reg_s17,
+ reg_s18,
+ reg_s19,
+ reg_s20,
+ reg_s21,
+ reg_s22,
+ reg_s23,
+ reg_s24,
+ reg_s25,
+ reg_s26,
+ reg_s27,
+ reg_s28,
+ reg_s29,
+ reg_s30,
+ reg_s31,
+ reg_h0,
+ reg_h1,
+ reg_h2,
+ reg_h3,
+ reg_h4,
+ reg_h5,
+ reg_h6,
+ reg_h7,
+ reg_h8,
+ reg_h9,
+ reg_h10,
+ reg_h11,
+ reg_h12,
+ reg_h13,
+ reg_h14,
+ reg_h15,
+ reg_h16,
+ reg_h17,
+ reg_h18,
+ reg_h19,
+ reg_h20,
+ reg_h21,
+ reg_h22,
+ reg_h23,
+ reg_h24,
+ reg_h25,
+ reg_h26,
+ reg_h27,
+ reg_h28,
+ reg_h29,
+ reg_h30,
+ reg_h31,
+ reg_fpsr,
+ reg_fpcr,
+ LLDB_INVALID_REGNUM // register sets need to end with this flag
+};
+
+// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1
+constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1;
+constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1;
+
+static RegisterSet g_reg_sets[] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums},
+ {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums},
+};
+
+constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets);
+
+RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64(
+ Thread &thread, const DataExtractor &data)
+ : RegisterContext(thread, 0) {
+ lldb::offset_t offset = 0;
+ m_regs.context_flags = data.GetU64(&offset);
+ for (unsigned i = 0; i < 32; ++i)
+ m_regs.x[i] = data.GetU64(&offset);
+ m_regs.pc = data.GetU64(&offset);
+ m_regs.cpsr = data.GetU32(&offset);
+ m_regs.fpsr = data.GetU32(&offset);
+ m_regs.fpcr = data.GetU32(&offset);
+ auto regs_data = data.GetData(&offset, sizeof(m_regs.v));
+ if (regs_data)
+ memcpy(m_regs.v, regs_data, sizeof(m_regs.v));
+ assert(k_num_regs == k_num_reg_infos);
+}
+size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; }
+
+const RegisterInfo *
+RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_reg_infos)
+ return &g_reg_infos[reg];
+ return nullptr;
+}
+
+size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() {
+ return k_num_reg_sets;
+}
+
+const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) {
+ if (set < k_num_reg_sets)
+ return &g_reg_sets[set];
+ return nullptr;
+}
+
+const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) {
+ if (reg < k_num_reg_infos)
+ return g_reg_infos[reg].name;
+ return nullptr;
+}
+
+bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ Status error;
+ reg_value.SetFromMemoryData(
+ reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset,
+ reg_info->byte_size, lldb::eByteOrderLittle, error);
+ return error.Success();
+}
+
+bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *,
+ const RegisterValue &) {
+ return false;
+}
+
+uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber(
+ lldb::RegisterKind kind, uint32_t num) {
+ for (size_t i = 0; i < k_num_regs; ++i) {
+ if (g_reg_infos[i].kinds[kind] == num)
+ return i;
+ }
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
new file mode 100644
index 000000000000..ee47b1577e52
--- /dev/null
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h
@@ -0,0 +1,83 @@
+//===-- RegisterContextMinidump_ARM64.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_RegisterContextMinidump_ARM64_h_
+#define liblldb_RegisterContextMinidump_ARM64_h_
+
+#include "MinidumpTypes.h"
+
+#include "Plugins/Process/Utility/RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitmaskEnum.h"
+
+// C includes
+// C++ includes
+
+namespace lldb_private {
+
+namespace minidump {
+
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext {
+public:
+ RegisterContextMinidump_ARM64(lldb_private::Thread &thread,
+ const DataExtractor &data);
+
+ ~RegisterContextMinidump_ARM64() override = default;
+
+ void InvalidateAllRegisters() override {
+ // Do nothing... registers are always valid...
+ }
+
+ size_t GetRegisterCount() override;
+
+ 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);
+
+ bool ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ bool WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+ // Reference: see breakpad/crashpad source
+ struct Context {
+ uint64_t context_flags;
+ uint64_t x[32];
+ uint64_t pc;
+ uint32_t cpsr;
+ uint32_t fpsr;
+ uint32_t fpcr;
+ uint8_t v[32 * 16]; // 32 128-bit floating point registers
+ };
+
+protected:
+ enum class Flags : uint32_t {
+ ARM64_Flag = 0x80000000,
+ Integer = ARM64_Flag | 0x00000002,
+ FloatingPoint = ARM64_Flag | 0x00000004,
+ LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint)
+ };
+ Context m_regs;
+};
+
+} // end namespace minidump
+} // end namespace lldb_private
+#endif // liblldb_RegisterContextMinidump_ARM64_h_
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
index 7605f8b143af..1fdbb5e3f1e5 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp
@@ -7,10 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "RegisterContextMinidump_x86_32.h"
-// Other libraries and framework includes
#include "lldb/Utility/DataBufferHeap.h"
// C includes
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
index e18bb3b4f5d9..38c2ffca4938 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h
@@ -10,10 +10,8 @@
#ifndef liblldb_RegisterContextMinidump_x86_32_h_
#define liblldb_RegisterContextMinidump_x86_32_h_
-// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterInfoInterface.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
index ba1cb6dbf3ef..eaa155de8eb9 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp
@@ -7,10 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "RegisterContextMinidump_x86_64.h"
-// Other libraries and framework includes
#include "lldb/Utility/DataBufferHeap.h"
// C includes
diff --git a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
index 9ba2ee9f29ad..30ce9065e141 100644
--- a/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
+++ b/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h
@@ -10,10 +10,8 @@
#ifndef liblldb_RegisterContextMinidump_h_
#define liblldb_RegisterContextMinidump_h_
-// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterInfoInterface.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp
index 3fafb6134e7f..f4c136577719 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
-// Project includes
#include "ThreadMinidump.h"
#include "ProcessMinidump.h"
+#include "RegisterContextMinidump_ARM.h"
+#include "RegisterContextMinidump_ARM64.h"
#include "RegisterContextMinidump_x86_32.h"
#include "RegisterContextMinidump_x86_64.h"
-// 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"
@@ -27,8 +27,6 @@
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
-// C Includes
-// C++ Includes
using namespace lldb;
using namespace lldb_private;
@@ -54,7 +52,6 @@ RegisterContextSP
ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
if (frame)
concrete_frame_idx = frame->GetConcreteFrameIndex();
@@ -88,15 +85,22 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
*this, reg_interface, gpregset, {}));
break;
}
- default:
+ case llvm::Triple::aarch64: {
+ DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
+ lldb::eByteOrderLittle, 8);
+ m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data));
break;
}
-
- if (!reg_interface) {
- if (log)
- log->Printf("elf-core::%s:: Architecture(%d) not supported",
- __FUNCTION__, arch.GetMachine());
- assert(false && "Architecture not supported");
+ case llvm::Triple::arm: {
+ DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(),
+ lldb::eByteOrderLittle, 8);
+ const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple;
+ m_thread_reg_ctx_sp.reset(
+ new RegisterContextMinidump_ARM(*this, data, apple));
+ break;
+ }
+ default:
+ break;
}
reg_ctx_sp = m_thread_reg_ctx_sp;
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h
index 74ac44f74dcf..45364facaa56 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.h
+++ b/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -10,14 +10,10 @@
#ifndef liblldb_ThreadMinidump_h_
#define liblldb_ThreadMinidump_h_
-// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
#include "lldb/Target/Thread.h"
-// C Includes
-// C++ Includes
namespace lldb_private {
diff --git a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
index 824579472b5e..8937d9843f87 100644
--- a/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
+++ b/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h
@@ -10,10 +10,6 @@
#ifndef liblldb_ScriptInterpreterNone_h_
#define liblldb_ScriptInterpreterNone_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Interpreter/ScriptInterpreter.h"
namespace lldb_private {
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 90d8ab97fb73..7e96dd9893c8 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -222,9 +222,7 @@ PythonBytes::~PythonBytes() {}
bool PythonBytes::Check(PyObject *py_obj) {
if (!py_obj)
return false;
- if (PyBytes_Check(py_obj))
- return true;
- return false;
+ return PyBytes_Check(py_obj);
}
void PythonBytes::Reset(PyRefType type, PyObject *py_obj) {
@@ -294,9 +292,7 @@ PythonByteArray::~PythonByteArray() {}
bool PythonByteArray::Check(PyObject *py_obj) {
if (!py_obj)
return false;
- if (PyByteArray_Check(py_obj))
- return true;
- return false;
+ return PyByteArray_Check(py_obj);
}
void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) {
@@ -939,7 +935,8 @@ PythonFile::PythonFile() : PythonObject() {}
PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); }
PythonFile::PythonFile(const char *path, const char *mode) {
- lldb_private::File file(path, GetOptionsFromMode(mode));
+ lldb_private::File file;
+ FileSystem::Instance().Open(file, FileSpec(path), GetOptionsFromMode(mode));
Reset(file, mode);
}
diff --git a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index beeb64782367..7cd98df28ee0 100644
--- a/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -15,10 +15,6 @@
// LLDB Python header must be included first
#include "lldb-python.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/Flags.h"
#include "lldb/Host/File.h"
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index b8eb36a2baf6..41cb443d4f1e 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -27,6 +27,7 @@
#include <string>
#include "lldb/API/SBValue.h"
+#include "lldb/API/SBFrame.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
@@ -91,6 +92,10 @@ static ScriptInterpreterPython::SWIGPythonCallModuleInit
g_swig_call_module_init = nullptr;
static ScriptInterpreterPython::SWIGPythonCreateOSPlugin
g_swig_create_os_plugin = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateFrameRecognizer
+ g_swig_create_frame_recognizer = nullptr;
+static ScriptInterpreterPython::SWIGPythonGetRecognizedArguments
+ g_swig_get_recognized_arguments = nullptr;
static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process
g_swig_run_script_keyword_process = nullptr;
static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread
@@ -107,6 +112,10 @@ static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan
g_swig_thread_plan_script = nullptr;
static ScriptInterpreterPython::SWIGPythonCallThreadPlan
g_swig_call_thread_plan = nullptr;
+static ScriptInterpreterPython::SWIGPythonCreateScriptedBreakpointResolver
+ g_swig_bkpt_resolver_script = nullptr;
+static ScriptInterpreterPython::SWIGPythonCallBreakpointResolver
+ g_swig_call_bkpt_resolver = nullptr;
static bool g_initialized = false;
@@ -128,6 +137,9 @@ public:
InitializePythonHome();
+ // Register _lldb as a built-in module.
+ PyImport_AppendInittab("_lldb", g_swig_init_callback);
+
// Python < 3.2 and Python >= 3.2 reversed the ordering requirements for
// calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you
// call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last.
@@ -196,7 +208,7 @@ ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter,
m_python_interpreter(py_interpreter) {
DoAcquireLock();
if ((on_entry & InitSession) == InitSession) {
- if (DoInitSession(on_entry, in, out, err) == false) {
+ if (!DoInitSession(on_entry, in, out, err)) {
// Don't teardown the session if we didn't init it.
m_teardown_session = false;
}
@@ -817,11 +829,15 @@ bool ScriptInterpreterPython::ExecuteOneLine(
error_file_sp);
} else {
input_file_sp.reset(new StreamFile());
- input_file_sp->GetFile().Open(FileSystem::DEV_NULL,
- File::eOpenOptionRead);
+ FileSystem::Instance().Open(input_file_sp->GetFile(),
+ FileSpec(FileSystem::DEV_NULL),
+ File::eOpenOptionRead);
+
output_file_sp.reset(new StreamFile());
- output_file_sp->GetFile().Open(FileSystem::DEV_NULL,
- File::eOpenOptionWrite);
+ FileSystem::Instance().Open(output_file_sp->GetFile(),
+ FileSpec(FileSystem::DEV_NULL),
+ File::eOpenOptionWrite);
+
error_file_sp = output_file_sp;
}
@@ -1491,6 +1507,62 @@ bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input,
return true;
}
+StructuredData::GenericSP ScriptInterpreterPython::CreateFrameRecognizer(
+ const char *class_name) {
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::GenericSP();
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+ ret_val =
+ g_swig_create_frame_recognizer(class_name, m_dictionary_name.c_str());
+ }
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+}
+
+lldb::ValueObjectListSP ScriptInterpreterPython::GetRecognizedArguments(
+ const StructuredData::ObjectSP &os_plugin_object_sp,
+ lldb::StackFrameSP frame_sp) {
+ Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock);
+
+ if (!os_plugin_object_sp) return ValueObjectListSP();
+
+ StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric();
+ if (!generic) return nullptr;
+
+ PythonObject implementor(PyRefType::Borrowed,
+ (PyObject *)generic->GetValue());
+
+ if (!implementor.IsAllocated()) return ValueObjectListSP();
+
+ PythonObject py_return(
+ PyRefType::Owned,
+ (PyObject *)g_swig_get_recognized_arguments(implementor.get(), frame_sp));
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ if (py_return.get()) {
+ PythonList result_list(PyRefType::Borrowed, py_return.get());
+ ValueObjectListSP result = ValueObjectListSP(new ValueObjectList());
+ for (size_t i = 0; i < result_list.GetSize(); i++) {
+ PyObject *item = result_list.GetItemAtIndex(i).get();
+ lldb::SBValue *sb_value_ptr =
+ (lldb::SBValue *)g_swig_cast_to_sbvalue(item);
+ auto valobj_sp = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr);
+ if (valobj_sp) result->Append(valobj_sp);
+ }
+ return result;
+ }
+ return ValueObjectListSP();
+}
+
StructuredData::GenericSP ScriptInterpreterPython::OSPlugin_CreatePluginObject(
const char *class_name, lldb::ProcessSP process_sp) {
if (class_name == nullptr || class_name[0] == '\0')
@@ -1868,10 +1940,88 @@ lldb::StateType ScriptInterpreterPython::ScriptedThreadPlanGetRunState(
return lldb::eStateRunning;
}
+StructuredData::GenericSP
+ScriptInterpreterPython::CreateScriptedBreakpointResolver(
+ const char *class_name,
+ StructuredDataImpl *args_data,
+ lldb::BreakpointSP &bkpt_sp) {
+
+ if (class_name == nullptr || class_name[0] == '\0')
+ return StructuredData::GenericSP();
+
+ if (!bkpt_sp.get())
+ return StructuredData::GenericSP();
+
+ Debugger &debugger = bkpt_sp->GetTarget().GetDebugger();
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ ScriptInterpreterPython *python_interpreter =
+ static_cast<ScriptInterpreterPython *>(script_interpreter);
+
+ if (!script_interpreter)
+ return StructuredData::GenericSP();
+
+ void *ret_val;
+
+ {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+
+ ret_val = g_swig_bkpt_resolver_script(
+ class_name, python_interpreter->m_dictionary_name.c_str(),
+ args_data, bkpt_sp);
+ }
+
+ return StructuredData::GenericSP(new StructuredPythonObject(ret_val));
+}
+
+bool
+ScriptInterpreterPython::ScriptedBreakpointResolverSearchCallback(
+ StructuredData::GenericSP implementor_sp,
+ SymbolContext *sym_ctx) {
+ bool should_continue = false;
+
+ if (implementor_sp) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ should_continue
+ = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__callback__",
+ sym_ctx);
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ return should_continue;
+}
+
+lldb::SearchDepth
+ScriptInterpreterPython::ScriptedBreakpointResolverSearchDepth(
+ StructuredData::GenericSP implementor_sp) {
+ int depth_as_int = lldb::eSearchDepthModule;
+ if (implementor_sp) {
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ depth_as_int
+ = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__get_depth__", nullptr);
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ if (depth_as_int == lldb::eSearchDepthInvalid)
+ return lldb::eSearchDepthModule;
+
+ if (depth_as_int <= lldb::kLastSearchDepthKind)
+ return (lldb::SearchDepth) depth_as_int;
+ else
+ return lldb::eSearchDepthModule;
+}
+
StructuredData::ObjectSP
ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec,
lldb_private::Status &error) {
- if (!file_spec.Exists()) {
+ if (!FileSystem::Instance().Exists(file_spec)) {
error.SetErrorString("no such file");
return StructuredData::ObjectSP();
}
@@ -2603,7 +2753,8 @@ bool ScriptInterpreterPython::LoadScriptingModule(
lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
{
- FileSpec target_file(pathname, true);
+ FileSpec target_file(pathname);
+ FileSystem::Instance().Resolve(target_file);
std::string basename(target_file.GetFilename().GetCString());
StreamString command_stream;
@@ -2687,7 +2838,7 @@ bool ScriptInterpreterPython::LoadScriptingModule(
bool was_imported = (was_imported_globally || was_imported_locally);
- if (was_imported == true && can_reload == false) {
+ if (was_imported && !can_reload) {
error.SetErrorString("module already imported");
return false;
}
@@ -3100,6 +3251,8 @@ void ScriptInterpreterPython::InitializeInterpreter(
SWIGPythonCallCommandObject swig_call_command_object,
SWIGPythonCallModuleInit swig_call_module_init,
SWIGPythonCreateOSPlugin swig_create_os_plugin,
+ SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer,
+ SWIGPythonGetRecognizedArguments swig_get_recognized_arguments,
SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
@@ -3107,7 +3260,9 @@ void ScriptInterpreterPython::InitializeInterpreter(
SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
SWIGPython_GetDynamicSetting swig_plugin_get,
SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
- SWIGPythonCallThreadPlan swig_call_thread_plan) {
+ SWIGPythonCallThreadPlan swig_call_thread_plan,
+ SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,
+ SWIGPythonCallBreakpointResolver swig_call_bkpt_resolver) {
g_swig_init_callback = swig_init_callback;
g_swig_breakpoint_callback = swig_breakpoint_callback;
g_swig_watchpoint_callback = swig_watchpoint_callback;
@@ -3126,6 +3281,8 @@ void ScriptInterpreterPython::InitializeInterpreter(
g_swig_call_command_object = swig_call_command_object;
g_swig_call_module_init = swig_call_module_init;
g_swig_create_os_plugin = swig_create_os_plugin;
+ g_swig_create_frame_recognizer = swig_create_frame_recognizer;
+ g_swig_get_recognized_arguments = swig_get_recognized_arguments;
g_swig_run_script_keyword_process = swig_run_script_keyword_process;
g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
g_swig_run_script_keyword_target = swig_run_script_keyword_target;
@@ -3134,6 +3291,8 @@ void ScriptInterpreterPython::InitializeInterpreter(
g_swig_plugin_get = swig_plugin_get;
g_swig_thread_plan_script = swig_thread_plan_script;
g_swig_call_thread_plan = swig_call_thread_plan;
+ g_swig_bkpt_resolver_script = swig_bkpt_resolver_script;
+ g_swig_call_bkpt_resolver = swig_call_bkpt_resolver;
}
void ScriptInterpreterPython::InitializePrivate() {
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
index b13979dc069b..a047359883ce 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h
@@ -16,14 +16,10 @@
#else
-// C Includes
-// C++ Includes
#include <memory>
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "PythonDataObjects.h"
#include "lldb/Breakpoint/BreakpointOptions.h"
#include "lldb/Core/IOHandler.h"
@@ -81,10 +77,25 @@ public:
const char *method_name,
Event *event_sp, bool &got_error);
+ typedef void *(*SWIGPythonCreateScriptedBreakpointResolver)(
+ const char *python_class_name, const char *session_dictionary_name,
+ lldb_private::StructuredDataImpl *args_impl,
+ lldb::BreakpointSP &bkpt_sp);
+
+ typedef unsigned int (*SWIGPythonCallBreakpointResolver)(void *implementor,
+ const char *method_name,
+ lldb_private::SymbolContext *sym_ctx);
+
typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name,
const char *session_dictionary_name,
const lldb::ProcessSP &process_sp);
+ typedef void *(*SWIGPythonCreateFrameRecognizer)(
+ const char *python_class_name, const char *session_dictionary_name);
+
+ typedef void *(*SWIGPythonGetRecognizedArguments)(
+ void *implementor, const lldb::StackFrameSP &frame_sp);
+
typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor,
uint32_t max);
@@ -208,6 +219,26 @@ public:
lldb::StateType
ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
bool &script_error) override;
+
+ StructuredData::GenericSP
+ CreateScriptedBreakpointResolver(const char *class_name,
+ StructuredDataImpl *args_data,
+ lldb::BreakpointSP &bkpt_sp) override;
+ bool
+ ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP
+ implementor_sp,
+ SymbolContext *sym_ctx) override;
+
+ lldb::SearchDepth
+ ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP
+ implementor_sp) override;
+
+ StructuredData::GenericSP
+ CreateFrameRecognizer(const char *class_name) override;
+
+ lldb::ValueObjectListSP
+ GetRecognizedArguments(const StructuredData::ObjectSP &implementor,
+ lldb::StackFrameSP frame_sp) override;
StructuredData::GenericSP
OSPlugin_CreatePluginObject(const char *class_name,
@@ -404,6 +435,8 @@ public:
SWIGPythonCallCommandObject swig_call_command_object,
SWIGPythonCallModuleInit swig_call_module_init,
SWIGPythonCreateOSPlugin swig_create_os_plugin,
+ SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer,
+ SWIGPythonGetRecognizedArguments swig_get_recognized_arguments,
SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
@@ -411,7 +444,9 @@ public:
SWIGPythonScriptKeyword_Value swig_run_script_keyword_value,
SWIGPython_GetDynamicSetting swig_plugin_get,
SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script,
- SWIGPythonCallThreadPlan swig_call_thread_plan);
+ SWIGPythonCallThreadPlan swig_call_thread_plan,
+ SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script,
+ SWIGPythonCallBreakpointResolver swig_call_breakpoint_resolver);
const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
diff --git a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
index e33e26507fb1..6e3792bff9c4 100644
--- a/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
+++ b/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp
@@ -112,14 +112,14 @@ void SetGlobalEnableOptions(const DebuggerSP &debugger_sp,
/// Code to handle the StructuredDataDarwinLog settings
//------------------------------------------------------------------
-static PropertyDefinition g_properties[] = {
+static constexpr PropertyDefinition g_properties[] = {
{
"enable-on-startup", // name
OptionValue::eTypeBoolean, // type
true, // global
false, // default uint value
nullptr, // default cstring value
- nullptr, // enum values
+ {}, // enum values
"Enable Darwin os_log collection when debugged process is launched "
"or attached." // description
},
@@ -129,13 +129,11 @@ static PropertyDefinition g_properties[] = {
true, // global
0, // default uint value
"", // default cstring value
- nullptr, // enum values
+ {}, // enum values
"Specify the options to 'plugin structured-data darwin-log enable' "
"that should be applied when automatically enabling logging on "
"startup/attach." // description
- },
- // Last entry sentinel.
- {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}};
+ }};
enum { ePropertyEnableOnStartup = 0, ePropertyAutoEnableOptions = 1 };
@@ -402,23 +400,23 @@ static void RegisterFilterOperations() {
/// This resets the logging with whatever settings are currently set.
// -------------------------------------------------------------------------
-static OptionDefinition g_enable_option_table[] = {
+static constexpr OptionDefinition g_enable_option_table[] = {
// Source stream include/exclude options (the first-level filter). This one
// should be made as small as possible as everything that goes through here
// must be processed by the process monitor.
{LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
+ nullptr, {}, 0, eArgTypeNone,
"Specifies log messages from other related processes should be "
"included."},
{LLDB_OPT_SET_ALL, false, "debug", 'd', OptionParser::eNoArgument, nullptr,
- nullptr, 0, eArgTypeNone,
+ {}, 0, eArgTypeNone,
"Specifies debug-level log messages should be included. Specifying"
" --debug implies --info."},
{LLDB_OPT_SET_ALL, false, "info", 'i', OptionParser::eNoArgument, nullptr,
- nullptr, 0, eArgTypeNone,
+ {}, 0, eArgTypeNone,
"Specifies info-level log messages should be included."},
{LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument,
- nullptr, nullptr, 0, eArgRawInput,
+ nullptr, {}, 0, eArgRawInput,
// There doesn't appear to be a great way for me to have these multi-line,
// formatted tables in help. This looks mostly right but there are extra
// linefeeds added at seemingly random spots, and indentation isn't
@@ -452,52 +450,52 @@ static OptionDefinition g_enable_option_table[] = {
"Prefer character classes like [[:digit:]] to \\d and the like, as "
"getting the backslashes escaped through properly is error-prone."},
{LLDB_OPT_SET_ALL, false, "live-stream", 'l',
- OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
+ OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
"Specify whether logging events are live-streamed or buffered. "
"True indicates live streaming, false indicates buffered. The "
"default is true (live streaming). Live streaming will deliver "
"log messages with less delay, but buffered capture mode has less "
"of an observer effect."},
{LLDB_OPT_SET_ALL, false, "no-match-accepts", 'n',
- OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
+ OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
"Specify whether a log message that doesn't match any filter rule "
"is accepted or rejected, where true indicates accept. The "
"default is true."},
{LLDB_OPT_SET_ALL, false, "echo-to-stderr", 'e',
- OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
+ OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
"Specify whether os_log()/NSLog() messages are echoed to the "
"target program's stderr. When DarwinLog is enabled, we shut off "
"the mirroring of os_log()/NSLog() to the program's stderr. "
"Setting this flag to true will restore the stderr mirroring."
"The default is false."},
{LLDB_OPT_SET_ALL, false, "broadcast-events", 'b',
- OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,
+ OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean,
"Specify if the plugin should broadcast events. Broadcasting "
"log events is a requirement for displaying the log entries in "
"LLDB command-line. It is also required if LLDB clients want to "
"process log events. The default is true."},
// Message formatting options
{LLDB_OPT_SET_ALL, false, "timestamp-relative", 'r',
- OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,
+ OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone,
"Include timestamp in the message header when printing a log "
"message. The timestamp is relative to the first displayed "
"message."},
{LLDB_OPT_SET_ALL, false, "subsystem", 's', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
- "Include the subsystem in the the message header when displaying "
+ nullptr, {}, 0, eArgTypeNone,
+ "Include the subsystem in the message header when displaying "
"a log message."},
{LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
+ nullptr, {}, 0, eArgTypeNone,
"Include the category in the message header when displaying "
"a log message."},
{LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
+ nullptr, {}, 0, eArgTypeNone,
"Include the activity parent-child chain in the message header "
"when displaying a log message. The activity hierarchy is "
"displayed as {grandparent-activity}:"
"{parent-activity}:{activity}[:...]."},
{LLDB_OPT_SET_ALL, false, "all-fields", 'A', OptionParser::eNoArgument,
- nullptr, nullptr, 0, eArgTypeNone,
+ nullptr, {}, 0, eArgTypeNone,
"Shortcut to specify that all header fields should be displayed."}};
class EnableOptions : public Options {
@@ -1679,7 +1677,7 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) {
// Build up the module list.
FileSpecList module_spec_list;
auto module_file_spec =
- FileSpec(GetGlobalProperties()->GetLoggingModuleName(), false);
+ FileSpec(GetGlobalProperties()->GetLoggingModuleName());
module_spec_list.Append(module_file_spec);
// We aren't specifying a source file set.
diff --git a/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt b/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
new file mode 100644
index 000000000000..e93d0618a0e4
--- /dev/null
+++ b/source/Plugins/SymbolFile/Breakpad/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_lldb_library(lldbPluginSymbolFileBreakpad PLUGIN
+ SymbolFileBreakpad.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ lldbSymbol
+ lldbUtility
+ lldbPluginObjectFileBreakpad
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
new file mode 100644
index 000000000000..2cca7a66b014
--- /dev/null
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -0,0 +1,223 @@
+//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h"
+#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/TypeMap.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::breakpad;
+
+namespace {
+class LineIterator {
+public:
+ // begin iterator for sections of given type
+ LineIterator(ObjectFile &obj, ConstString section_type)
+ : m_obj(&obj), m_section_type(section_type), m_next_section_idx(0) {
+ ++*this;
+ }
+
+ // end iterator
+ explicit LineIterator(ObjectFile &obj)
+ : m_obj(&obj),
+ m_next_section_idx(m_obj->GetSectionList()->GetNumSections(0)) {}
+
+ friend bool operator!=(const LineIterator &lhs, const LineIterator &rhs) {
+ assert(lhs.m_obj == rhs.m_obj);
+ if (lhs.m_next_section_idx != rhs.m_next_section_idx)
+ return true;
+ if (lhs.m_next_text.data() != rhs.m_next_text.data())
+ return true;
+ assert(lhs.m_current_text == rhs.m_current_text);
+ assert(rhs.m_next_text == rhs.m_next_text);
+ return false;
+ }
+
+ const LineIterator &operator++();
+ llvm::StringRef operator*() const { return m_current_text; }
+
+private:
+ ObjectFile *m_obj;
+ ConstString m_section_type;
+ uint32_t m_next_section_idx;
+ llvm::StringRef m_current_text;
+ llvm::StringRef m_next_text;
+};
+} // namespace
+
+const LineIterator &LineIterator::operator++() {
+ const SectionList &list = *m_obj->GetSectionList();
+ size_t num_sections = list.GetNumSections(0);
+ while (m_next_text.empty() && m_next_section_idx < num_sections) {
+ Section &sect = *list.GetSectionAtIndex(m_next_section_idx++);
+ if (sect.GetName() != m_section_type)
+ continue;
+ DataExtractor data;
+ m_obj->ReadSectionData(&sect, data);
+ m_next_text =
+ llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
+ data.GetByteSize());
+ }
+ std::tie(m_current_text, m_next_text) = m_next_text.split('\n');
+ return *this;
+}
+
+static llvm::iterator_range<LineIterator> lines(ObjectFile &obj,
+ ConstString section_type) {
+ return llvm::make_range(LineIterator(obj, section_type), LineIterator(obj));
+}
+
+void SymbolFileBreakpad::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+}
+
+void SymbolFileBreakpad::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+ConstString SymbolFileBreakpad::GetPluginNameStatic() {
+ static ConstString g_name("breakpad");
+ return g_name;
+}
+
+uint32_t SymbolFileBreakpad::CalculateAbilities() {
+ if (!m_obj_file)
+ return 0;
+ if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic())
+ return 0;
+
+ return CompileUnits | Functions;
+}
+
+uint32_t SymbolFileBreakpad::GetNumCompileUnits() {
+ // TODO
+ return 0;
+}
+
+CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
+ // TODO
+ return nullptr;
+}
+
+size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
+ // TODO
+ return 0;
+}
+
+bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
+ // TODO
+ return 0;
+}
+
+uint32_t
+SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
+ SymbolContextItem resolve_scope,
+ SymbolContext &sc) {
+ // TODO
+ return 0;
+}
+
+uint32_t SymbolFileBreakpad::FindFunctions(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask, bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ // TODO
+ if (!append)
+ sc_list.Clear();
+ return sc_list.GetSize();
+}
+
+uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ // TODO
+ if (!append)
+ sc_list.Clear();
+ return sc_list.GetSize();
+}
+
+uint32_t SymbolFileBreakpad::FindTypes(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
+ if (!append)
+ types.Clear();
+ return types.GetSize();
+}
+
+size_t
+SymbolFileBreakpad::FindTypes(const std::vector<CompilerContext> &context,
+ bool append, TypeMap &types) {
+ if (!append)
+ types.Clear();
+ return types.GetSize();
+}
+
+void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
+ Module &module = *m_obj_file->GetModule();
+ addr_t base = module.GetObjectFile()->GetBaseAddress().GetFileAddress();
+ if (base == LLDB_INVALID_ADDRESS) {
+ LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
+ "symtab population.");
+ return;
+ }
+
+ const SectionList &list = *module.GetSectionList();
+ for (llvm::StringRef line : lines(*m_obj_file, ConstString("PUBLIC"))) {
+ // PUBLIC [m] address param_size name
+ // skip PUBLIC keyword
+ line = getToken(line).second;
+ llvm::StringRef token;
+ std::tie(token, line) = getToken(line);
+ if (token == "m")
+ std::tie(token, line) = getToken(line);
+
+ addr_t address;
+ if (!to_integer(token, address, 16))
+ continue;
+ address += base;
+
+ // skip param_size
+ line = getToken(line).second;
+
+ llvm::StringRef name = line.trim();
+
+ SectionSP section_sp = list.FindSectionContainingFileAddress(address);
+ if (!section_sp) {
+ LLDB_LOG(log,
+ "Ignoring symbol {0}, whose address ({1}) is outside of the "
+ "object file. Mismatched symbol file?",
+ name, address);
+ continue;
+ }
+
+ symtab.AddSymbol(Symbol(
+ /*symID*/ 0, Mangled(name, /*is_mangled*/ false), eSymbolTypeCode,
+ /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false,
+ /*is_artificial*/ false,
+ AddressRange(section_sp, address - section_sp->GetFileAddress(), 0),
+ /*size_is_valid*/ 0, /*contains_linker_annotations*/ false,
+ /*flags*/ 0));
+ }
+
+ // TODO: Process FUNC records as well.
+
+ symtab.CalculateSymbolSizes();
+}
diff --git a/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
new file mode 100644
index 000000000000..68e8d11c7dd7
--- /dev/null
+++ b/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -0,0 +1,146 @@
+//===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H
+
+#include "lldb/Symbol/SymbolFile.h"
+
+namespace lldb_private {
+
+namespace breakpad {
+
+class SymbolFileBreakpad : public SymbolFile {
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+ static void Terminate();
+ static void DebuggerInitialize(Debugger &debugger) {}
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic() {
+ return "Breakpad debug symbol file reader.";
+ }
+
+ static SymbolFile *CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileBreakpad(obj_file);
+ }
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {}
+
+ ~SymbolFileBreakpad() override {}
+
+ uint32_t CalculateAbilities() override;
+
+ void InitializeObject() override {}
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+
+ uint32_t GetNumCompileUnits() override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override {
+ return lldb::eLanguageTypeUnknown;
+ }
+
+ size_t ParseFunctions(CompileUnit &comp_unit) override;
+
+ bool ParseLineTable(CompileUnit &comp_unit) override;
+
+ bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; }
+
+ bool ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) override {
+ return false;
+ }
+ size_t ParseTypes(CompileUnit &cu) override { return 0; }
+
+ bool
+ ParseImportedModules(const SymbolContext &sc,
+ std::vector<ConstString> &imported_modules) override {
+ return false;
+ }
+
+ size_t ParseBlocksRecursive(Function &func) override { return 0; }
+
+ uint32_t FindGlobalVariables(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override {
+ return 0;
+ }
+
+ size_t ParseVariablesForContext(const SymbolContext &sc) override {
+ return 0;
+ }
+ Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; }
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override {
+ return llvm::None;
+ }
+
+ bool CompleteType(CompilerType &compiler_type) override { return false; }
+ uint32_t ResolveSymbolContext(const Address &so_addr,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc) override;
+
+ size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override {
+ return 0;
+ }
+
+ uint32_t FindFunctions(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) override;
+
+ uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
+ bool append, SymbolContextList &sc_list) override;
+
+ uint32_t FindTypes(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
+
+ size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
+ TypeMap &types) override;
+
+ TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override {
+ return nullptr;
+ }
+
+ CompilerDeclContext
+ FindNamespace(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) override {
+ return CompilerDeclContext();
+ }
+
+ void AddSymbols(Symtab &symtab) override;
+
+ ConstString GetPluginName() override { return GetPluginNameStatic(); }
+ uint32_t GetPluginVersion() override { return 1; }
+
+private:
+};
+
+} // namespace breakpad
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/CMakeLists.txt b/source/Plugins/SymbolFile/CMakeLists.txt
index 98510704ce73..ad1c92bd8469 100644
--- a/source/Plugins/SymbolFile/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/CMakeLists.txt
@@ -1,3 +1,5 @@
+add_subdirectory(Breakpad)
add_subdirectory(DWARF)
add_subdirectory(Symtab)
+add_subdirectory(NativePDB)
add_subdirectory(PDB)
diff --git a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
index f62a496f808a..0e47ee34fe51 100644
--- a/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -4,9 +4,6 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN
DIERef.cpp
DWARFAbbreviationDeclaration.cpp
DWARFASTParserClang.cpp
- DWARFASTParserGo.cpp
- DWARFASTParserJava.cpp
- DWARFASTParserOCaml.cpp
DWARFAttribute.cpp
DWARFBaseDIE.cpp
DWARFCompileUnit.cpp
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index ae7c770d6ef7..24d5f26745dc 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -12,10 +12,16 @@
#include "DWARFDefines.h"
#include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
class DWARFDIE;
+namespace lldb_private {
+class CompileUnit;
+class ExecutionContext;
+}
+class SymbolFileDWARF;
class DWARFASTParser {
public:
@@ -27,7 +33,7 @@ public:
bool *type_is_new_ptr) = 0;
virtual lldb_private::Function *
- ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
+ ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
const DWARFDIE &die) = 0;
virtual bool
@@ -45,6 +51,10 @@ public:
virtual std::vector<DWARFDIE>
GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0;
+
+ static llvm::Optional<lldb_private::SymbolFile::ArrayInfo>
+ ParseChildArrayInfo(const DWARFDIE &parent_die,
+ const lldb_private::ExecutionContext *exe_ctx = nullptr);
};
#endif // SymbolFileDWARF_DWARFASTParser_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index fe6f1be3ca48..70d48e5f1dfa 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -125,7 +125,7 @@ ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
}
/// Detect a forward declaration that is nested in a DW_TAG_module.
-static bool isClangModuleFwdDecl(const DWARFDIE &Die) {
+static bool IsClangModuleFwdDecl(const DWARFDIE &Die) {
if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0))
return false;
auto Parent = Die.GetParent();
@@ -142,30 +142,31 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
if (!dwo_module_sp)
return TypeSP();
- // This type comes from an external DWO module.
- std::vector<CompilerContext> dwo_context;
- die.GetDWOContext(dwo_context);
+ // If this type comes from a Clang module, look in the DWARF section
+ // of the pcm file in the module cache. Clang generates DWO skeleton
+ // units as breadcrumbs to find them.
+ std::vector<CompilerContext> decl_context;
+ die.GetDeclContext(decl_context);
TypeMap dwo_types;
- if (!dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true,
+ if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true,
dwo_types)) {
- if (!isClangModuleFwdDecl(die))
+ if (!IsClangModuleFwdDecl(die))
return TypeSP();
// Since this this type is defined in one of the Clang modules imported by
// this symbol file, search all of them.
- auto *SymFile = die.GetCU()->GetSymbolFileDWARF();
- for (const auto &NameModule : SymFile->getExternalTypeModules()) {
- if (!NameModule.second)
+ auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
+ for (const auto &name_module : sym_file->getExternalTypeModules()) {
+ if (!name_module.second)
continue;
- SymbolVendor *SymVendor = NameModule.second->GetSymbolVendor();
- if (SymVendor->FindTypes(dwo_context, true, dwo_types))
+ SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
+ if (sym_vendor->FindTypes(decl_context, true, dwo_types))
break;
}
}
- const size_t num_dwo_types = dwo_types.GetSize();
- if (num_dwo_types != 1)
+ if (dwo_types.GetSize() != 1)
return TypeSP();
// We found a real definition for this type in the Clang module, so lets use
@@ -307,14 +308,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
decl.SetColumn(form_value.Unsigned());
break;
case DW_AT_name:
-
type_name_cstr = form_value.AsCString();
- // Work around a bug in llvm-gcc where they give a name to a
- // reference type which doesn't include the "&"...
- if (tag == DW_TAG_reference_type) {
- if (strchr(type_name_cstr, '&') == NULL)
- type_name_cstr = NULL;
- }
if (type_name_cstr)
type_name_const_str.SetCString(type_name_cstr);
break;
@@ -421,8 +415,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (!clang_type &&
(encoding_data_type == Type::eEncodingIsPointerUID ||
- encoding_data_type == Type::eEncodingIsTypedefUID) &&
- sc.comp_unit != NULL) {
+ encoding_data_type == Type::eEncodingIsTypedefUID)) {
if (tag == DW_TAG_pointer_type) {
DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
@@ -558,16 +551,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
case DW_AT_decl_file:
- if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) {
- // llvm-gcc outputs invalid DW_AT_decl_file attributes that
- // always point to the compile unit file, so we clear this
- // invalid value so that we can still unique types
- // efficiently.
- decl.SetFile(FileSpec("<invalid>", false));
- } else
- decl.SetFile(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
+ decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ form_value.Unsigned()));
break;
case DW_AT_decl_line:
@@ -671,7 +656,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
if (byte_size_valid && byte_size == 0 && type_name_cstr &&
- die.HasChildren() == false &&
+ !die.HasChildren() &&
sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
// Work around an issue with clang at the moment where forward
// declarations for objective C classes are emitted as:
@@ -909,7 +894,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// has child classes or types that require the class to be created
// for use as their decl contexts the class will be ready to accept
// these child definitions.
- if (die.HasChildren() == false) {
+ if (!die.HasChildren()) {
// No children for this struct/union/class, lets finish it
if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
@@ -1308,10 +1293,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
if (die.HasChildren()) {
bool skip_artificial = true;
- ParseChildParameters(sc, containing_decl_ctx, die, skip_artificial,
- is_static, is_variadic, has_template_params,
- function_param_types, function_param_decls,
- type_quals);
+ ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die,
+ skip_artificial, is_static, is_variadic,
+ has_template_params, function_param_types,
+ function_param_decls, type_quals);
}
bool ignore_containing_context = false;
@@ -1748,16 +1733,19 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
if (element_type) {
- std::vector<uint64_t> element_orders;
- ParseChildArrayInfo(sc, die, first_index, element_orders,
- byte_stride, bit_stride);
+ auto array_info = ParseChildArrayInfo(die);
+ if (array_info) {
+ first_index = array_info->first_index;
+ byte_stride = array_info->byte_stride;
+ bit_stride = array_info->bit_stride;
+ }
if (byte_stride == 0 && bit_stride == 0)
byte_stride = element_type->GetByteSize();
CompilerType array_element_type =
element_type->GetForwardCompilerType();
if (ClangASTContext::IsCXXClassType(array_element_type) &&
- array_element_type.GetCompleteType() == false) {
+ !array_element_type.GetCompleteType()) {
ModuleSP module_sp = die.GetModule();
if (module_sp) {
if (die.GetCU()->GetProducer() == eProducerClang)
@@ -1800,12 +1788,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
}
uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
- if (element_orders.size() > 0) {
+ if (array_info && array_info->element_orders.size() > 0) {
uint64_t num_elements = 0;
- std::vector<uint64_t>::const_reverse_iterator pos;
- std::vector<uint64_t>::const_reverse_iterator end =
- element_orders.rend();
- for (pos = element_orders.rbegin(); pos != end; ++pos) {
+ auto end = array_info->element_orders.rend();
+ for (auto pos = array_info->element_orders.rbegin(); pos != end;
+ ++pos) {
num_elements = *pos;
clang_type = m_ast.CreateArrayType(array_element_type,
num_elements, is_vector);
@@ -1824,6 +1811,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID,
&decl, clang_type, Type::eResolveStateFull));
type_sp->SetEncodingType(element_type);
+ m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(),
+ die.GetID());
}
}
} break;
@@ -1861,12 +1850,14 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
clang_type = ClangASTContext::CreateMemberPointerType(
class_clang_type, pointee_clang_type);
- byte_size = clang_type.GetByteSize(nullptr);
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_size, NULL, LLDB_INVALID_UID,
- Type::eEncodingIsUID, NULL, clang_type,
- Type::eResolveStateForward));
+ if (llvm::Optional<uint64_t> clang_type_size =
+ clang_type.GetByteSize(nullptr)) {
+ byte_size = *clang_type_size;
+ type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
+ byte_size, NULL, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, NULL, clang_type,
+ Type::eResolveStateForward));
+ }
}
break;
@@ -2056,7 +2047,10 @@ bool DWARFASTParserClang::ParseTemplateDIE(
clang_type.IsIntegerOrEnumerationType(is_signed);
if (tag == DW_TAG_template_value_parameter && uval64_valid) {
- llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed);
+ llvm::Optional<uint64_t> size = clang_type.GetBitSize(nullptr);
+ if (!size)
+ return false;
+ llvm::APInt apint(*size, uval64, is_signed);
template_param_infos.args.push_back(
clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed),
ClangUtil::GetQualType(clang_type)));
@@ -2108,95 +2102,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
return template_param_infos.args.size() == template_param_infos.names.size();
}
-// Checks whether m1 is an overload of m2 (as opposed to an override). This is
-// called by addOverridesForMethod to distinguish overrides (which share a
-// vtable entry) from overloads (which require distinct entries).
-static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) {
- // FIXME: This should detect covariant return types, but currently doesn't.
- lldbassert(&m1->getASTContext() == &m2->getASTContext() &&
- "Methods should have the same AST context");
- clang::ASTContext &context = m1->getASTContext();
-
- const auto *m1Type =
- llvm::cast<clang::FunctionProtoType>(
- context.getCanonicalType(m1->getType()));
-
- const auto *m2Type =
- llvm::cast<clang::FunctionProtoType>(
- context.getCanonicalType(m2->getType()));
-
- auto compareArgTypes =
- [&context](const clang::QualType &m1p, const clang::QualType &m2p) {
- return context.hasSameType(m1p.getUnqualifiedType(),
- m2p.getUnqualifiedType());
- };
-
- // FIXME: In C++14 and later, we can just pass m2Type->param_type_end()
- // as a fourth parameter to std::equal().
- return (m1->getNumParams() != m2->getNumParams()) ||
- !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(),
- m2Type->param_type_begin(), compareArgTypes);
-}
-
-// If decl is a virtual method, walk the base classes looking for methods that
-// decl overrides. This table of overridden methods is used by IRGen to
-// determine the vtable layout for decl's parent class.
-static void addOverridesForMethod(clang::CXXMethodDecl *decl) {
- if (!decl->isVirtual())
- return;
-
- clang::CXXBasePaths paths;
-
- auto find_overridden_methods =
- [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) {
- if (auto *base_record =
- llvm::dyn_cast<clang::CXXRecordDecl>(
- specifier->getType()->getAs<clang::RecordType>()->getDecl())) {
-
- clang::DeclarationName name = decl->getDeclName();
-
- // If this is a destructor, check whether the base class destructor is
- // virtual.
- if (name.getNameKind() == clang::DeclarationName::CXXDestructorName)
- if (auto *baseDtorDecl = base_record->getDestructor()) {
- if (baseDtorDecl->isVirtual()) {
- path.Decls = baseDtorDecl;
- return true;
- } else
- return false;
- }
-
- // Otherwise, search for name in the base class.
- for (path.Decls = base_record->lookup(name); !path.Decls.empty();
- path.Decls = path.Decls.slice(1)) {
- if (auto *method_decl =
- llvm::dyn_cast<clang::CXXMethodDecl>(path.Decls.front()))
- if (method_decl->isVirtual() && !isOverload(decl, method_decl)) {
- path.Decls = method_decl;
- return true;
- }
- }
- }
-
- return false;
- };
-
- if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) {
- for (auto *overridden_decl : paths.found_decls())
- decl->addOverriddenMethod(
- llvm::cast<clang::CXXMethodDecl>(overridden_decl));
- }
-}
-
-// If clang_type is a CXXRecordDecl, builds the method override list for each
-// of its virtual methods.
-static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) {
- if (auto *record =
- ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()))
- for (auto *method : record->methods())
- addOverridesForMethod(method);
-}
-
bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
lldb_private::Type *type,
CompilerType &clang_type) {
@@ -2287,14 +2192,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
}
SymbolContext sc(die.GetLLDBCompileUnit());
- std::vector<clang::CXXBaseSpecifier *> base_classes;
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
std::vector<int> member_accessibilities;
bool is_a_class = false;
// Parse members and base classes first
DWARFDIECollection member_function_dies;
DelayedPropertyList delayed_properties;
- ParseChildMembers(sc, die, clang_type, class_language, base_classes,
+ ParseChildMembers(sc, die, clang_type, class_language, bases,
member_accessibilities, member_function_dies,
delayed_properties, default_accessibility, is_a_class,
layout_info);
@@ -2358,17 +2263,17 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
&member_accessibilities.front(), member_accessibilities.size());
}
- if (!base_classes.empty()) {
+ if (!bases.empty()) {
// Make sure all base classes refer to complete types and not forward
// declarations. If we don't do this, clang will crash with an
- // assertion in the call to clang_type.SetBaseClassesForClassType()
- for (auto &base_class : base_classes) {
+ // assertion in the call to clang_type.TransferBaseClasses()
+ for (const auto &base_class : bases) {
clang::TypeSourceInfo *type_source_info =
base_class->getTypeSourceInfo();
if (type_source_info) {
CompilerType base_class_type(
&m_ast, type_source_info->getType().getAsOpaquePtr());
- if (base_class_type.GetCompleteType() == false) {
+ if (!base_class_type.GetCompleteType()) {
auto module = dwarf->GetObjectFile()->GetModule();
module->ReportError(":: Class '%s' has a base class '%s' which "
"does not have a complete definition.",
@@ -2381,7 +2286,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
// We have no choice other than to pretend that the base class
// is complete. If we don't do this, clang will crash when we
// call setBases() inside of
- // "clang_type.SetBaseClassesForClassType()" below. Since we
+ // "clang_type.TransferBaseClasses()" below. Since we
// provide layout assistance, all ivars in this class and other
// classes will be fine, this is the best we can do short of
// crashing.
@@ -2393,19 +2298,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
}
}
}
- m_ast.SetBaseClassesForClassType(clang_type.GetOpaqueQualType(),
- &base_classes.front(),
- base_classes.size());
-
- // Clang will copy each CXXBaseSpecifier in "base_classes" so we have
- // to free them all.
- ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(),
- base_classes.size());
+
+ m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
+ std::move(bases));
}
}
}
- addMethodOverrides(m_ast, clang_type);
+ m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType());
ClangASTContext::BuildIndirectFields(clang_type);
ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
@@ -2604,9 +2504,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
if (name && name[0] && got_value) {
m_ast.AddEnumerationValueToEnumerationType(
- clang_type.GetOpaqueQualType(),
- m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()),
- decl, name, enum_value, enumerator_byte_size * 8);
+ clang_type, decl, name, enum_value, enumerator_byte_size * 8);
++enumerators_added;
}
}
@@ -2663,7 +2561,7 @@ protected:
};
#endif
-Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
+Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
const DWARFDIE &die) {
DWARFRangeList func_ranges;
const char *name = NULL;
@@ -2724,9 +2622,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
clang::DeclContext *containing_decl_ctx =
GetClangDeclContextContainingDIE(die, nullptr);
- ParseChildParameters(sc, containing_decl_ctx, die, true, is_static,
- is_variadic, has_template_params, param_types,
- param_decls, type_quals);
+ ParseChildParameters(comp_unit, containing_decl_ctx, die, true,
+ is_static, is_variadic, has_template_params,
+ param_types, param_decls, type_quals);
sstr << "(";
for (size_t i = 0; i < param_types.size(); i++) {
if (i > 0)
@@ -2747,7 +2645,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
std::unique_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
+ comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line, decl_column));
SymbolFileDWARF *dwarf = die.GetDWARF();
@@ -2758,7 +2656,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
const user_id_t func_user_id = die.GetID();
- func_sp.reset(new Function(sc.comp_unit,
+ func_sp.reset(new Function(&comp_unit,
func_user_id, // UserID is the DIE offset
func_user_id, func_name, func_type,
func_range)); // first address range
@@ -2766,7 +2664,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
if (func_sp.get() != NULL) {
if (frame_base.IsValid())
func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
+ comp_unit.AddFunction(func_sp);
return func_sp.get();
}
}
@@ -2778,7 +2676,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
bool DWARFASTParserClang::ParseChildMembers(
const SymbolContext &sc, const DWARFDIE &parent_die,
CompilerType &class_clang_type, const LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *> &base_classes,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
std::vector<int> &member_accessibilities,
DWARFDIECollection &member_function_dies,
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
@@ -2977,15 +2875,6 @@ bool DWARFASTParserClang::ParseChildMembers(
class_language == eLanguageTypeObjC_plus_plus)
accessibility = eAccessNone;
- if (member_idx == 0 && !is_artificial && name &&
- (strstr(name, "_vptr$") == name)) {
- // Not all compilers will mark the vtable pointer member as
- // artificial (llvm-gcc). We can't have the virtual members in our
- // classes otherwise it throws off all child offsets since we end up
- // having and extra pointer sized member in our class layouts.
- is_artificial = true;
- }
-
// Handle static members
if (is_external && member_byte_offset == UINT32_MAX) {
Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
@@ -3000,7 +2889,7 @@ bool DWARFASTParserClang::ParseChildMembers(
break;
}
- if (is_artificial == false) {
+ if (!is_artificial) {
Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
clang::FieldDecl *field_decl = NULL;
@@ -3141,7 +3030,7 @@ bool DWARFASTParserClang::ParseChildMembers(
if (anon_field_info.IsValid()) {
clang::FieldDecl *unnamed_bitfield_decl =
ClangASTContext::AddFieldToRecordType(
- class_clang_type, NULL,
+ class_clang_type, llvm::StringRef(),
m_ast.GetBuiltinTypeForEncodingAndBitSize(
eEncodingSint, word_width),
accessibility, anon_field_info.bit_size);
@@ -3198,7 +3087,7 @@ bool DWARFASTParserClang::ParseChildMembers(
}
if (ClangASTContext::IsCXXClassType(member_clang_type) &&
- member_clang_type.GetCompleteType() == false) {
+ !member_clang_type.GetCompleteType()) {
if (die.GetCU()->GetProducer() == eProducerClang)
module_sp->ReportError(
"DWARF DIE at 0x%8.8x (class %s) has a member variable "
@@ -3383,9 +3272,14 @@ bool DWARFASTParserClang::ParseChildMembers(
if (class_language == eLanguageTypeObjC) {
ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
} else {
- base_classes.push_back(ast->CreateBaseClassSpecifier(
- base_class_clang_type.GetOpaqueQualType(), accessibility,
- is_virtual, is_base_of_class));
+ std::unique_ptr<clang::CXXBaseSpecifier> result =
+ ast->CreateBaseClassSpecifier(
+ base_class_clang_type.GetOpaqueQualType(), accessibility,
+ is_virtual, is_base_of_class);
+ if (!result)
+ break;
+
+ base_classes.push_back(std::move(result));
if (is_virtual) {
// Do not specify any offset for virtual inheritance. The DWARF
@@ -3419,7 +3313,7 @@ bool DWARFASTParserClang::ParseChildMembers(
}
size_t DWARFASTParserClang::ParseChildParameters(
- const SymbolContext &sc, clang::DeclContext *containing_decl_ctx,
+ CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx,
const DWARFDIE &parent_die, bool skip_artificial, bool &is_static,
bool &is_variadic, bool &has_template_params,
std::vector<CompilerType> &function_param_types,
@@ -3451,7 +3345,7 @@ size_t DWARFASTParserClang::ParseChildParameters(
if (attributes.ExtractFormValueAtIndex(i, form_value)) {
switch (attr) {
case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
+ decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(
form_value.Unsigned()));
break;
case DW_AT_decl_line:
@@ -3517,8 +3411,9 @@ size_t DWARFASTParserClang::ParseChildParameters(
function_param_types.push_back(type->GetForwardCompilerType());
clang::ParmVarDecl *param_var_decl =
- m_ast.CreateParameterDeclaration(
- name, type->GetForwardCompilerType(), storage);
+ m_ast.CreateParameterDeclaration(containing_decl_ctx, name,
+ type->GetForwardCompilerType(),
+ storage);
assert(param_var_decl);
function_param_decls.push_back(param_var_decl);
@@ -3551,12 +3446,12 @@ size_t DWARFASTParserClang::ParseChildParameters(
return arg_idx;
}
-void DWARFASTParserClang::ParseChildArrayInfo(
- const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
- std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
- uint32_t &bit_stride) {
+llvm::Optional<SymbolFile::ArrayInfo>
+DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
+ const ExecutionContext *exe_ctx) {
+ SymbolFile::ArrayInfo array_info;
if (!parent_die)
- return;
+ return llvm::None;
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
die = die.GetSibling()) {
@@ -3580,15 +3475,31 @@ void DWARFASTParserClang::ParseChildArrayInfo(
break;
case DW_AT_count:
- num_elements = form_value.Unsigned();
+ if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
+ if (var_die.Tag() == DW_TAG_variable)
+ if (exe_ctx) {
+ if (auto frame = exe_ctx->GetFrameSP()) {
+ Status error;
+ lldb::VariableSP var_sp;
+ auto valobj_sp = frame->GetValueForVariableExpressionPath(
+ var_die.GetName(), eNoDynamicValues, 0, var_sp,
+ error);
+ if (valobj_sp) {
+ num_elements = valobj_sp->GetValueAsUnsigned(0);
+ break;
+ }
+ }
+ }
+ } else
+ num_elements = form_value.Unsigned();
break;
case DW_AT_bit_stride:
- bit_stride = form_value.Unsigned();
+ array_info.bit_stride = form_value.Unsigned();
break;
case DW_AT_byte_stride:
- byte_stride = form_value.Unsigned();
+ array_info.byte_stride = form_value.Unsigned();
break;
case DW_AT_lower_bound:
@@ -3622,11 +3533,12 @@ void DWARFASTParserClang::ParseChildArrayInfo(
num_elements = upper_bound - lower_bound + 1;
}
- element_orders.push_back(num_elements);
+ array_info.element_orders.push_back(num_elements);
}
} break;
}
}
+ return array_info;
}
Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 57c1fc07b2b6..63e058d7bf21 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -10,15 +10,11 @@
#ifndef SymbolFileDWARF_DWARFASTParserClang_h_
#define SymbolFileDWARF_DWARFASTParserClang_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "clang/AST/CharUnits.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-// Project includes
#include "DWARFASTParser.h"
#include "DWARFDefines.h"
#include "lldb/Core/ClangForward.h"
@@ -26,8 +22,12 @@
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTImporter.h"
+namespace lldb_private {
+class CompileUnit;
+}
class DWARFDebugInfoEntry;
class DWARFDIECollection;
+class SymbolFileDWARF;
class DWARFASTParserClang : public DWARFASTParser {
public:
@@ -41,7 +41,7 @@ public:
bool *type_is_new_ptr) override;
lldb_private::Function *
- ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
+ ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
const DWARFDIE &die) override;
bool
@@ -80,19 +80,19 @@ protected:
lldb_private::ClangASTContext::TemplateParameterInfos
&template_param_infos);
- bool
- ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type,
- const lldb::LanguageType class_language,
- std::vector<clang::CXXBaseSpecifier *> &base_classes,
- std::vector<int> &member_accessibilities,
- DWARFDIECollection &member_function_dies,
- DelayedPropertyList &delayed_properties,
- lldb::AccessType &default_accessibility, bool &is_a_class,
- lldb_private::ClangASTImporter::LayoutInfo &layout_info);
+ bool ParseChildMembers(
+ const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+ lldb_private::CompilerType &class_compiler_type,
+ const lldb::LanguageType class_language,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
+ std::vector<int> &member_accessibilities,
+ DWARFDIECollection &member_function_dies,
+ DelayedPropertyList &delayed_properties,
+ lldb::AccessType &default_accessibility, bool &is_a_class,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
- ParseChildParameters(const lldb_private::SymbolContext &sc,
+ ParseChildParameters(lldb_private::CompileUnit &comp_unit,
clang::DeclContext *containing_decl_ctx,
const DWARFDIE &parent_die, bool skip_artificial,
bool &is_static, bool &is_variadic,
@@ -101,11 +101,6 @@ protected:
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals);
- void ParseChildArrayInfo(const lldb_private::SymbolContext &sc,
- const DWARFDIE &parent_die, int64_t &first_index,
- std::vector<uint64_t> &element_orders,
- uint32_t &byte_stride, uint32_t &bit_stride);
-
size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc,
lldb_private::CompilerType &compiler_type,
bool is_signed, uint32_t enumerator_byte_size,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
deleted file mode 100644
index 328212e4b684..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-//===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFASTParserGo.h"
-
-#include "DWARFASTParserGo.h"
-#include "DWARFDIE.h"
-#include "DWARFDIECollection.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFDeclContext.h"
-#include "DWARFDefines.h"
-#include "SymbolFileDWARF.h"
-#include "SymbolFileDWARFDebugMap.h"
-#include "UniqueDWARFASTType.h"
-
-#include "clang/Basic/Specifiers.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/Value.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/TypeList.h"
-
-//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
-
-#ifdef ENABLE_DEBUG_PRINTF
-#include <stdio.h>
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
-
-#define DW_AT_go_kind 0x2900
-#define DW_AT_go_key 0x2901
-#define DW_AT_go_elem 0x2902
-
-using namespace lldb;
-using namespace lldb_private;
-DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {}
-
-DWARFASTParserGo::~DWARFASTParserGo() {}
-
-TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die,
- lldb_private::Log *log, bool *type_is_new_ptr) {
- TypeSP type_sp;
-
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
-
- if (die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = "
- "'%s')",
- die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
- }
-
- Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
- TypeList *type_list = dwarf->GetTypeList();
- if (type_ptr == NULL) {
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
-
- const dw_tag_t tag = die.Tag();
-
- bool is_forward_declaration = false;
- DWARFAttributes attributes;
- const char *type_name_cstr = NULL;
- ConstString type_name_const_str;
- Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
- uint64_t byte_size = 0;
- uint64_t go_kind = 0;
- Declaration decl;
-
- Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
- CompilerType compiler_type;
- DWARFFormValue form_value;
-
- dw_attr_t attr;
-
- switch (tag) {
- case DW_TAG_base_type:
- case DW_TAG_pointer_type:
- case DW_TAG_typedef:
- case DW_TAG_unspecified_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- if (type_name_cstr)
- type_name_const_str.SetCString(type_name_cstr);
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_encoding:
- // = form_value.Unsigned();
- break;
- case DW_AT_type:
- encoding_uid = form_value.Reference();
- break;
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
- default:
- // Do we care about DW_AT_go_key or DW_AT_go_elem?
- break;
- }
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
- die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
- encoding_uid);
-
- switch (tag) {
- default:
- break;
-
- case DW_TAG_unspecified_type:
- resolve_state = Type::eResolveStateFull;
- compiler_type = m_ast.CreateVoidType(type_name_const_str);
- break;
-
- case DW_TAG_base_type:
- resolve_state = Type::eResolveStateFull;
- compiler_type =
- m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size);
- break;
-
- case DW_TAG_pointer_type:
- encoding_data_type = Type::eEncodingIsPointerUID;
- break;
- case DW_TAG_typedef:
- encoding_data_type = Type::eEncodingIsTypedefUID;
- CompilerType impl;
- Type *type = dwarf->ResolveTypeUID(encoding_uid);
- if (type) {
- if (go_kind == 0 && type->GetName() == type_name_const_str) {
- // Go emits extra typedefs as a forward declaration. Ignore
- // these.
- dwarf->m_die_to_type[die.GetDIE()] = type;
- return type->shared_from_this();
- }
- impl = type->GetForwardCompilerType();
- compiler_type =
- m_ast.CreateTypedefType(go_kind, type_name_const_str, impl);
- }
- break;
- }
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_size, NULL, encoding_uid,
- encoding_data_type, &decl, compiler_type,
- resolve_state));
-
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- } break;
-
- case DW_TAG_structure_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
- bool byte_size_valid = false;
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- byte_size_valid = true;
- break;
-
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
-
- // TODO: Should we use SLICETYPE's DW_AT_go_elem?
- default:
- break;
- }
- }
- }
- }
-
- // TODO(ribrdb): Do we need this?
-
- // UniqueDWARFASTType is large, so don't create a local variables on
- // the stack, put it on the heap. This function is often called
- // recursively and clang isn't good and sharing the stack space for
- // variables in different blocks.
- std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
- new UniqueDWARFASTType());
-
- // Only try and unique the type if it has a name.
- if (type_name_const_str &&
- dwarf->GetUniqueDWARFASTTypeMap().Find(
- type_name_const_str, die, decl,
- byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
- // We have already parsed this type or from another compile unit. GCC
- // loves to use the "one definition rule" which can result in
- // multiple definitions of the same class over and over in each
- // compile unit.
- type_sp = unique_ast_entry_ap->m_type_sp;
- if (type_sp) {
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- bool compiler_type_was_created = false;
- compiler_type.SetCompilerType(
- &m_ast,
- dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
- if (!compiler_type) {
- compiler_type_was_created = true;
- compiler_type =
- m_ast.CreateStructType(go_kind, type_name_const_str, byte_size);
- }
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_size, NULL, LLDB_INVALID_UID,
- Type::eEncodingIsUID, &decl, compiler_type,
- Type::eResolveStateForward));
-
- // Add our type to the unique type map so we don't end up creating many
- // copies of the same type over and over in the ASTContext for our
- // module
- unique_ast_entry_ap->m_type_sp = type_sp;
- unique_ast_entry_ap->m_die = die;
- unique_ast_entry_ap->m_declaration = decl;
- unique_ast_entry_ap->m_byte_size = byte_size;
- dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str,
- *unique_ast_entry_ap);
-
- if (!is_forward_declaration) {
- // Always start the definition for a class type so that if the class
- // has child classes or types that require the class to be created
- // for use as their decl contexts the class will be ready to accept
- // these child definitions.
- if (die.HasChildren() == false) {
- // No children for this struct/union/class, lets finish it
- m_ast.CompleteStructType(compiler_type);
- } else if (compiler_type_was_created) {
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
- compiler_type.GetOpaqueQualType();
- dwarf->m_forward_decl_clang_type_to_die[compiler_type
- .GetOpaqueQualType()] =
- die.GetDIERef();
- // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
- }
- }
- } break;
-
- case DW_TAG_subprogram:
- case DW_TAG_subroutine_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- bool is_variadic = false;
- clang::StorageClass storage =
- clang::SC_None; //, Extern, Static, PrivateExtern
-
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_external:
- if (form_value.Unsigned()) {
- if (storage == clang::SC_None)
- storage = clang::SC_Extern;
- else
- storage = clang::SC_PrivateExtern;
- }
- break;
-
- case DW_AT_high_pc:
- case DW_AT_low_pc:
- break;
- }
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- std::vector<CompilerType> function_param_types;
-
- // Parse the function children for the parameters
-
- if (die.HasChildren()) {
- ParseChildParameters(sc, die, is_variadic, function_param_types);
- }
-
- // compiler_type will get the function prototype clang type after this
- // call
- compiler_type = m_ast.CreateFunctionType(
- type_name_const_str, function_param_types.data(),
- function_param_types.size(), is_variadic);
-
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
- LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
- compiler_type, Type::eResolveStateFull));
- assert(type_sp.get());
- } break;
-
- case DW_TAG_array_type: {
- // Set a bit that lets us know that we are currently parsing this
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
- int64_t first_index = 0;
- uint32_t byte_stride = 0;
- uint32_t bit_stride = 0;
- const size_t num_attributes = die.GetAttributes(attributes);
-
- if (num_attributes > 0) {
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name_cstr = form_value.AsCString();
- type_name_const_str.SetCString(type_name_cstr);
- break;
-
- case DW_AT_type:
- type_die_offset = form_value.Reference();
- break;
- case DW_AT_byte_size:
- break; // byte_size = form_value.Unsigned(); break;
- case DW_AT_go_kind:
- go_kind = form_value.Unsigned();
- break;
- default:
- break;
- }
- }
- }
-
- DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
- DW_TAG_value_to_name(tag), type_name_cstr);
-
- Type *element_type = dwarf->ResolveTypeUID(type_die_offset);
-
- if (element_type) {
- std::vector<uint64_t> element_orders;
- ParseChildArrayInfo(sc, die, first_index, element_orders,
- byte_stride, bit_stride);
- if (byte_stride == 0)
- byte_stride = element_type->GetByteSize();
- CompilerType array_element_type =
- element_type->GetForwardCompilerType();
- if (element_orders.size() > 0) {
- if (element_orders.size() > 1)
- printf("golang: unsupported multi-dimensional array %s\n",
- type_name_cstr);
- compiler_type = m_ast.CreateArrayType(
- type_name_const_str, array_element_type, element_orders[0]);
- } else {
- compiler_type = m_ast.CreateArrayType(type_name_const_str,
- array_element_type, 0);
- }
- type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
- byte_stride, NULL, type_die_offset,
- Type::eEncodingIsUID, &decl, compiler_type,
- Type::eResolveStateFull));
- type_sp->SetEncodingType(element_type);
- }
- }
- } break;
-
- default:
- dwarf->GetObjectFile()->GetModule()->ReportError(
- "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), "
- "please file a bug and attach the file at the "
- "start of this error message",
- die.GetOffset(), tag, DW_TAG_value_to_name(tag));
- break;
- }
-
- if (type_sp.get()) {
- DWARFDIE sc_parent_die =
- SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
-
- SymbolContextScope *symbol_context_scope = NULL;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != NULL && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == NULL)
- symbol_context_scope = sc.function;
- }
-
- if (symbol_context_scope != NULL) {
- type_sp->SetSymbolContextScope(symbol_context_scope);
- }
-
- // We are ready to put this type into the uniqued list up at the module
- // level
- type_list->Insert(type_sp);
-
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
- }
- } else if (type_ptr != DIE_IS_BEING_PARSED) {
- type_sp = type_ptr->shared_from_this();
- }
- }
- return type_sp;
-}
-
-size_t DWARFASTParserGo::ParseChildParameters(
- const SymbolContext &sc,
-
- const DWARFDIE &parent_die, bool &is_variadic,
- std::vector<CompilerType> &function_param_types) {
- if (!parent_die)
- return 0;
-
- size_t arg_idx = 0;
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
-
- dw_tag_t tag = die.Tag();
- switch (tag) {
- case DW_TAG_formal_parameter: {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- Declaration decl;
- DWARFFormValue param_type_die_offset;
-
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- // = form_value.AsCString();
- break;
- case DW_AT_type:
- param_type_die_offset = form_value;
- break;
- case DW_AT_location:
- // if (form_value.BlockData())
- // {
- // const DWARFDataExtractor&
- // debug_info_data =
- // debug_info();
- // uint32_t block_length =
- // form_value.Unsigned();
- // DWARFDataExtractor
- // location(debug_info_data,
- // form_value.BlockData() -
- // debug_info_data.GetDataStart(),
- // block_length);
- // }
- // else
- // {
- // }
- // break;
- default:
- break;
- }
- }
- }
-
- Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset));
- if (type) {
- function_param_types.push_back(type->GetForwardCompilerType());
- }
- }
- arg_idx++;
- } break;
-
- case DW_TAG_unspecified_parameters:
- is_variadic = true;
- break;
-
- default:
- break;
- }
- }
- return arg_idx;
-}
-
-void DWARFASTParserGo::ParseChildArrayInfo(
- const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
- std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
- uint32_t &bit_stride) {
- if (!parent_die)
- return;
-
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
- const dw_tag_t tag = die.Tag();
- switch (tag) {
- case DW_TAG_subrange_type: {
- DWARFAttributes attributes;
- const size_t num_child_attributes = die.GetAttributes(attributes);
- if (num_child_attributes > 0) {
- uint64_t num_elements = 0;
- uint32_t i;
- for (i = 0; i < num_child_attributes; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_count:
- num_elements = form_value.Unsigned();
- break;
-
- default:
- case DW_AT_type:
- break;
- }
- }
- }
-
- element_orders.push_back(num_elements);
- }
- } break;
- }
- }
-}
-
-bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die,
- lldb_private::Type *type,
- CompilerType &compiler_type) {
- if (!die)
- return false;
-
- const dw_tag_t tag = die.Tag();
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
- Log *log =
- nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
- if (log)
- dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
- die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString());
- assert(compiler_type);
- DWARFAttributes attributes;
-
- switch (tag) {
- case DW_TAG_structure_type: {
- {
- if (die.HasChildren()) {
- SymbolContext sc(die.GetLLDBCompileUnit());
-
- ParseChildMembers(sc, die, compiler_type);
- }
- }
- m_ast.CompleteStructType(compiler_type);
- return (bool)compiler_type;
- }
-
- default:
- assert(false && "not a forward go type decl!");
- break;
- }
-
- return false;
-}
-
-size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc,
- const DWARFDIE &parent_die,
- CompilerType &class_compiler_type) {
- size_t count = 0;
- uint32_t member_idx = 0;
-
- ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
- GoASTContext *ast =
- llvm::dyn_cast_or_null<GoASTContext>(class_compiler_type.GetTypeSystem());
- if (ast == nullptr)
- return 0;
-
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
- dw_tag_t tag = die.Tag();
-
- switch (tag) {
- case DW_TAG_member: {
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- Declaration decl;
- const char *name = NULL;
-
- DWARFFormValue encoding_uid;
- uint32_t member_byte_offset = UINT32_MAX;
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- case DW_AT_data_member_location:
- if (form_value.BlockData()) {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- NULL, // ExecutionContext *
- NULL, // RegisterContext *
- module_sp, debug_info_data, die.GetCU(), block_offset,
- block_length, eRegisterKindDWARF, &initialValue, NULL,
- memberOffset, NULL)) {
- member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
- }
- } else {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning of
- // the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid));
- if (member_type) {
- CompilerType member_go_type = member_type->GetFullCompilerType();
- ConstString name_const_str(name);
- m_ast.AddFieldToStruct(class_compiler_type, name_const_str,
- member_go_type, member_byte_offset);
- }
- }
- ++member_idx;
- } break;
-
- default:
- break;
- }
- }
-
- return count;
-}
-
-Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die) {
- DWARFRangeList func_ranges;
- const char *name = NULL;
- const char *mangled = NULL;
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- DWARFExpression frame_base(die.GetCU());
-
- assert(die.Tag() == DW_TAG_subprogram);
-
- if (die.Tag() != DW_TAG_subprogram)
- return NULL;
-
- if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
- decl_column, call_file, call_line, call_column,
- &frame_base)) {
- // Union of all ranges in the function DIE (if the function is
- // discontiguous)
- AddressRange func_range;
- lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
- lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
- if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
- lowest_func_addr <= highest_func_addr) {
- ModuleSP module_sp(die.GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections(
- lowest_func_addr, module_sp->GetSectionList());
- if (func_range.GetBaseAddress().IsValid())
- func_range.SetByteSize(highest_func_addr - lowest_func_addr);
- }
-
- if (func_range.GetBaseAddress().IsValid()) {
- Mangled func_name;
- func_name.SetValue(ConstString(name), false);
-
- FunctionSP func_sp;
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
- // Supply the type _only_ if it has already been parsed
- Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
-
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
-
- if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
- const user_id_t func_user_id = die.GetID();
- func_sp.reset(new Function(sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id, func_name, func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL) {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
- }
- }
- }
- }
- return NULL;
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
deleted file mode 100644
index 2a7c3871a309..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- DWARFASTParserGo.h --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFASTParserGo_h_
-#define SymbolFileDWARF_DWARFASTParserGo_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-// Project includes
-#include "DWARFASTParser.h"
-#include "DWARFDIE.h"
-#include "DWARFDefines.h"
-#include "lldb/Core/PluginInterface.h"
-#include "lldb/Symbol/GoASTContext.h"
-
-class DWARFDebugInfoEntry;
-class DWARFDIECollection;
-
-class DWARFASTParserGo : public DWARFASTParser {
-public:
- DWARFASTParserGo(lldb_private::GoASTContext &ast);
-
- ~DWARFASTParserGo() override;
-
- lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
- bool *type_is_new_ptr) override;
-
- lldb_private::Function *
- ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die) override;
-
- bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
- lldb_private::CompilerType &go_type) override;
-
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDeclContext();
- }
-
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDeclContext();
- }
-
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDecl();
- }
-
- std::vector<DWARFDIE> GetDIEForDeclContext(
- lldb_private::CompilerDeclContext decl_context) override {
- return std::vector<DWARFDIE>();
- }
-
-private:
- size_t ParseChildParameters(
- const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die,
- bool &is_variadic,
- std::vector<lldb_private::CompilerType> &function_param_types);
- void ParseChildArrayInfo(const lldb_private::SymbolContext &sc,
- const DWARFDIE &parent_die, int64_t &first_index,
- std::vector<uint64_t> &element_orders,
- uint32_t &byte_stride, uint32_t &bit_stride);
-
- size_t ParseChildMembers(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type);
-
- lldb_private::GoASTContext &m_ast;
-};
-
-#endif // SymbolFileDWARF_DWARFASTParserGo_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
deleted file mode 100644
index 476394487985..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DWARFASTParserJava.h"
-#include "DWARFAttribute.h"
-#include "DWARFUnit.h"
-#include "DWARFDebugInfoEntry.h"
-#include "DWARFDebugInfoEntry.h"
-#include "DWARFDeclContext.h"
-#include "SymbolFileDWARF.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/SymbolContextScope.h"
-#include "lldb/Symbol/TypeList.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {}
-
-DWARFASTParserJava::~DWARFASTParserJava() {}
-
-TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- ConstString type_name;
- uint64_t byte_size = 0;
-
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name.SetCString(form_value.AsCString());
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_encoding:
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_base_type");
- }
- }
- }
-
- Declaration decl;
- CompilerType compiler_type = m_ast.CreateBaseType(type_name);
- return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
- nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
- decl, compiler_type, Type::eResolveStateFull);
-}
-
-TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- ConstString linkage_name;
- DWARFFormValue type_attr_value;
- lldb::addr_t data_offset = LLDB_INVALID_ADDRESS;
- DWARFExpression length_expression(die.GetCU());
-
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_linkage_name:
- linkage_name.SetCString(form_value.AsCString());
- break;
- case DW_AT_type:
- type_attr_value = form_value;
- break;
- case DW_AT_data_member_location:
- data_offset = form_value.Unsigned();
- break;
- case DW_AT_declaration:
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_array_type");
- }
- }
- }
-
- for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
- child_die = child_die.GetSibling()) {
- if (child_die.Tag() == DW_TAG_subrange_type) {
- DWARFAttributes attributes;
- const size_t num_attributes = child_die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_count:
- if (form_value.BlockData())
- length_expression.CopyOpcodeData(
- form_value.BlockData(), form_value.Unsigned(),
- child_die.GetCU()->GetByteOrder(),
- child_die.GetCU()->GetAddressByteSize());
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_subrange_type");
- }
- }
- }
- } else {
- assert(false && "Unsupported child for DW_TAG_array_type");
- }
- }
-
- DIERef type_die_ref(type_attr_value);
- Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
- if (!element_type)
- return nullptr;
-
- CompilerType element_compiler_type = element_type->GetForwardCompilerType();
- CompilerType array_compiler_type = m_ast.CreateArrayType(
- linkage_name, element_compiler_type, length_expression, data_offset);
-
- Declaration decl;
- TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(),
- -1, nullptr, type_die_ref.GetUID(dwarf),
- Type::eEncodingIsUID, &decl, array_compiler_type,
- Type::eResolveStateFull));
- type_sp->SetEncodingType(element_type);
- return type_sp;
-}
-
-TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- Declaration decl;
- DWARFFormValue type_attr_value;
-
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_type:
- type_attr_value = form_value;
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_array_type");
- }
- }
- }
-
- DIERef type_die_ref(type_attr_value);
- Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref);
- if (!pointee_type)
- return nullptr;
-
- CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType();
- CompilerType reference_compiler_type =
- m_ast.CreateReferenceType(pointee_compiler_type);
- TypeSP type_sp(
- new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1,
- nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl,
- reference_compiler_type, Type::eResolveStateFull));
- type_sp->SetEncodingType(pointee_type);
- return type_sp;
-}
-
-lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
- bool &is_new_type) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- Declaration decl;
- ConstString name;
- ConstString linkage_name;
- bool is_forward_declaration = false;
- uint32_t byte_size = 0;
-
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- name.SetCString(form_value.AsCString());
- break;
- case DW_AT_declaration:
- is_forward_declaration = form_value.Boolean();
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_linkage_name:
- linkage_name.SetCString(form_value.AsCString());
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_class_type");
- }
- }
- }
-
- UniqueDWARFASTType unique_ast_entry;
- if (name) {
- std::string qualified_name;
- if (die.GetQualifiedName(qualified_name)) {
- name.SetCString(qualified_name.c_str());
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
- unique_ast_entry)) {
- if (unique_ast_entry.m_type_sp) {
- dwarf->GetDIEToType()[die.GetDIE()] =
- unique_ast_entry.m_type_sp.get();
- is_new_type = false;
- return unique_ast_entry.m_type_sp;
- }
- }
- }
- }
-
- if (is_forward_declaration) {
- DWARFDeclContext die_decl_ctx;
- die.GetDWARFDeclContext(die_decl_ctx);
-
- TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
- if (type_sp) {
- // We found a real definition for this type elsewhere so lets use it
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- is_new_type = false;
- return type_sp;
- }
- }
-
- CompilerType compiler_type(
- &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
- if (!compiler_type)
- compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
-
- is_new_type = true;
- TypeSP type_sp(new Type(die.GetID(), dwarf, name,
- -1, // byte size isn't specified
- nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
- &decl, compiler_type, Type::eResolveStateForward));
-
- // Add our type to the unique type map
- unique_ast_entry.m_type_sp = type_sp;
- unique_ast_entry.m_die = die;
- unique_ast_entry.m_declaration = decl;
- unique_ast_entry.m_byte_size = -1;
- dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry);
-
- if (!is_forward_declaration) {
- // Leave this as a forward declaration until we need to know the details of
- // the type
- dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
- compiler_type.GetOpaqueQualType();
- dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
- die.GetDIERef();
- }
- return type_sp;
-}
-
-lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die,
- lldb_private::Log *log, bool *type_is_new_ptr) {
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
-
- if (!die)
- return nullptr;
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
-
- Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
- if (type_ptr == DIE_IS_BEING_PARSED)
- return nullptr;
- if (type_ptr != nullptr)
- return type_ptr->shared_from_this();
-
- TypeSP type_sp;
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
-
- switch (die.Tag()) {
- case DW_TAG_base_type: {
- type_sp = ParseBaseTypeFromDIE(die);
- break;
- }
- case DW_TAG_array_type: {
- type_sp = ParseArrayTypeFromDIE(die);
- break;
- }
- case DW_TAG_class_type: {
- bool is_new_type = false;
- type_sp = ParseClassTypeFromDIE(die, is_new_type);
- if (!is_new_type)
- return type_sp;
- break;
- }
- case DW_TAG_reference_type: {
- type_sp = ParseReferenceTypeFromDIE(die);
- break;
- }
- }
-
- if (!type_sp)
- return nullptr;
-
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
-
- SymbolContextScope *symbol_context_scope = nullptr;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != nullptr && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == nullptr)
- symbol_context_scope = sc.function;
- }
-
- if (symbol_context_scope != nullptr)
- type_sp->SetSymbolContextScope(symbol_context_scope);
-
- dwarf->GetTypeList()->Insert(type_sp);
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
-
- return type_sp;
-}
-
-lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF(
- const lldb_private::SymbolContext &sc, const DWARFDIE &die) {
- assert(die.Tag() == DW_TAG_subprogram);
-
- const char *name = nullptr;
- const char *mangled = nullptr;
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- DWARFRangeList func_ranges;
- DWARFExpression frame_base(die.GetCU());
-
- if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
- decl_column, call_file, call_line, call_column,
- &frame_base)) {
- // Union of all ranges in the function DIE (if the function is
- // discontiguous)
- AddressRange func_range;
- lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
- lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
- if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
- lowest_func_addr <= highest_func_addr) {
- ModuleSP module_sp(die.GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections(
- lowest_func_addr, module_sp->GetSectionList());
- if (func_range.GetBaseAddress().IsValid())
- func_range.SetByteSize(highest_func_addr - lowest_func_addr);
- }
-
- if (func_range.GetBaseAddress().IsValid()) {
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
-
- if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) {
- FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(),
- Mangled(ConstString(name), false),
- nullptr, // No function types in java
- func_range));
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
-
- return func_sp.get();
- }
- }
- }
- return nullptr;
-}
-
-bool DWARFASTParserJava::CompleteTypeFromDWARF(
- const DWARFDIE &die, lldb_private::Type *type,
- lldb_private::CompilerType &java_type) {
- switch (die.Tag()) {
- case DW_TAG_class_type: {
- if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) {
- if (die.HasChildren())
- ParseChildMembers(die, java_type);
- m_ast.CompleteObjectType(java_type);
- return java_type.IsValid();
- }
- } break;
- default:
- assert(false && "Not a forward java type declaration!");
- break;
- }
- return false;
-}
-
-void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die,
- CompilerType &compiler_type) {
- DWARFUnit *dwarf_cu = parent_die.GetCU();
- for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
- die = die.GetSibling()) {
- switch (die.Tag()) {
- case DW_TAG_member: {
- const char *name = nullptr;
- DWARFFormValue encoding_uid;
- uint32_t member_byte_offset = UINT32_MAX;
- DWARFExpression member_location_expression(dwarf_cu);
-
- DWARFAttributes attributes;
- size_t num_attributes = die.GetAttributes(attributes);
- for (size_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attributes.AttributeAtIndex(i)) {
- case DW_AT_name:
- name = form_value.AsCString();
- break;
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- case DW_AT_data_member_location:
- if (form_value.BlockData())
- member_location_expression.CopyOpcodeData(
- form_value.BlockData(), form_value.Unsigned(),
- dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize());
- else
- member_byte_offset = form_value.Unsigned();
- break;
- case DW_AT_artificial:
- static_cast<void>(form_value.Boolean());
- break;
- case DW_AT_accessibility:
- // TODO: Handle when needed
- break;
- default:
- assert(false && "Unhandled attribute for DW_TAG_member");
- break;
- }
- }
- }
-
- if (strcmp(name, ".dynamic_type") == 0)
- m_ast.SetDynamicTypeId(compiler_type, member_location_expression);
- else {
- if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)))
- m_ast.AddMemberToObject(compiler_type, ConstString(name),
- member_type->GetFullCompilerType(),
- member_byte_offset);
- }
- break;
- }
- case DW_TAG_inheritance: {
- DWARFFormValue encoding_uid;
- uint32_t member_byte_offset = UINT32_MAX;
-
- DWARFAttributes attributes;
- size_t num_attributes = die.GetAttributes(attributes);
- for (size_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attributes.AttributeAtIndex(i)) {
- case DW_AT_type:
- encoding_uid = form_value;
- break;
- case DW_AT_data_member_location:
- member_byte_offset = form_value.Unsigned();
- break;
- case DW_AT_accessibility:
- // In java all base class is public so we can ignore this attribute
- break;
- default:
- assert(false && "Unhandled attribute for DW_TAG_member");
- break;
- }
- }
- }
- if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid)))
- m_ast.AddBaseClassToObject(compiler_type,
- base_type->GetFullCompilerType(),
- member_byte_offset);
- break;
- }
- default:
- break;
- }
- }
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
deleted file mode 100644
index 01d81833d517..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SymbolFileDWARF_DWARFASTParserJava_h_
-#define SymbolFileDWARF_DWARFASTParserJava_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-// Project includes
-#include "DWARFASTParser.h"
-#include "DWARFDIE.h"
-#include "DWARFDefines.h"
-#include "lldb/Core/PluginInterface.h"
-#include "lldb/Symbol/JavaASTContext.h"
-
-class DWARFDebugInfoEntry;
-class DWARFDIECollection;
-
-class DWARFASTParserJava : public DWARFASTParser {
-public:
- DWARFASTParserJava(lldb_private::JavaASTContext &ast);
- ~DWARFASTParserJava() override;
-
- lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
- bool *type_is_new_ptr) override;
-
- lldb_private::Function *
- ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die) override;
-
- bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
- lldb_private::CompilerType &java_type) override;
-
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDeclContext();
- }
-
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDeclContext();
- }
-
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDecl();
- }
-
- std::vector<DWARFDIE> GetDIEForDeclContext(
- lldb_private::CompilerDeclContext decl_context) override {
- return std::vector<DWARFDIE>();
- }
-
- void ParseChildMembers(const DWARFDIE &parent_die,
- lldb_private::CompilerType &class_compiler_type);
-
-private:
- lldb_private::JavaASTContext &m_ast;
-
- lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die);
-
- lldb::TypeSP ParseArrayTypeFromDIE(const DWARFDIE &die);
-
- lldb::TypeSP ParseReferenceTypeFromDIE(const DWARFDIE &die);
-
- lldb::TypeSP ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type);
-};
-
-#endif // SymbolFileDWARF_DWARFASTParserJava_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
deleted file mode 100644
index 3ef5c2eb8626..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===//
-
-#include "DWARFASTParserOCaml.h"
-
-#include "lldb/Core/Module.h"
-#include "lldb/Symbol/CompileUnit.h"
-#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/Type.h"
-#include "lldb/Symbol/TypeList.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {}
-
-DWARFASTParserOCaml::~DWARFASTParserOCaml() {}
-
-TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
- ConstString type_name;
- uint64_t byte_size = 0;
-
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- for (uint32_t i = 0; i < num_attributes; ++i) {
- DWARFFormValue form_value;
- dw_attr_t attr = attributes.AttributeAtIndex(i);
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_name:
- type_name.SetCString(form_value.AsCString());
- break;
- case DW_AT_byte_size:
- byte_size = form_value.Unsigned();
- break;
- case DW_AT_encoding:
- break;
- default:
- assert(false && "Unsupported attribute for DW_TAG_base_type");
- }
- }
- }
-
- Declaration decl;
- CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size);
- return std::make_shared<Type>(die.GetID(), dwarf, type_name, byte_size,
- nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
- decl, compiler_type, Type::eResolveStateFull);
-}
-
-lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die,
- Log *log,
- bool *type_is_new_ptr) {
- if (type_is_new_ptr)
- *type_is_new_ptr = false;
-
- if (!die)
- return nullptr;
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
-
- Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
- if (type_ptr == DIE_IS_BEING_PARSED)
- return nullptr;
- if (type_ptr != nullptr)
- return type_ptr->shared_from_this();
-
- TypeSP type_sp;
- if (type_is_new_ptr)
- *type_is_new_ptr = true;
-
- switch (die.Tag()) {
- case DW_TAG_base_type: {
- type_sp = ParseBaseTypeFromDIE(die);
- break;
- }
- case DW_TAG_array_type: {
- break;
- }
- case DW_TAG_class_type: {
- break;
- }
- case DW_TAG_reference_type: {
- break;
- }
- }
-
- if (!type_sp)
- return nullptr;
-
- DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
- dw_tag_t sc_parent_tag = sc_parent_die.Tag();
-
- SymbolContextScope *symbol_context_scope = nullptr;
- if (sc_parent_tag == DW_TAG_compile_unit ||
- sc_parent_tag == DW_TAG_partial_unit) {
- symbol_context_scope = sc.comp_unit;
- } else if (sc.function != nullptr && sc_parent_die) {
- symbol_context_scope =
- sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
- if (symbol_context_scope == nullptr)
- symbol_context_scope = sc.function;
- }
-
- if (symbol_context_scope != nullptr)
- type_sp->SetSymbolContextScope(symbol_context_scope);
-
- dwarf->GetTypeList()->Insert(type_sp);
- dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
-
- return type_sp;
-}
-
-Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc,
- const DWARFDIE &die) {
- DWARFRangeList func_ranges;
- const char *name = NULL;
- const char *mangled = NULL;
- int decl_file = 0;
- int decl_line = 0;
- int decl_column = 0;
- int call_file = 0;
- int call_line = 0;
- int call_column = 0;
- DWARFExpression frame_base(die.GetCU());
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
-
- if (die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s "
- "name = '%s')",
- die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
- }
- }
-
- assert(die.Tag() == DW_TAG_subprogram);
-
- if (die.Tag() != DW_TAG_subprogram)
- return NULL;
-
- if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
- decl_column, call_file, call_line, call_column,
- &frame_base)) {
- AddressRange func_range;
- lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
- lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
- if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
- lowest_func_addr <= highest_func_addr) {
- ModuleSP module_sp(die.GetModule());
- func_range.GetBaseAddress().ResolveAddressUsingFileSections(
- lowest_func_addr, module_sp->GetSectionList());
- if (func_range.GetBaseAddress().IsValid())
- func_range.SetByteSize(highest_func_addr - lowest_func_addr);
- }
-
- if (func_range.GetBaseAddress().IsValid()) {
- Mangled func_name;
-
- func_name.SetValue(ConstString(name), true);
-
- FunctionSP func_sp;
- std::unique_ptr<Declaration> decl_ap;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
- decl_line, decl_column));
-
- SymbolFileDWARF *dwarf = die.GetDWARF();
- Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
-
- assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
-
- if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
- const user_id_t func_user_id = die.GetID();
- func_sp.reset(new Function(sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id, func_name, func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL) {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
- }
- }
- }
- }
-
- return NULL;
-}
-
-lldb_private::CompilerDeclContext
-DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
- return CompilerDeclContext();
-}
-
-lldb_private::CompilerDeclContext
-DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
- return CompilerDeclContext();
-}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
deleted file mode 100644
index 09cb5e14934f..000000000000
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===//
-
-#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_
-#define SymbolFileDWARF_DWARFASTParserOCaml_h_
-
-#include "DWARFASTParser.h"
-#include "DWARFDIE.h"
-#include "DWARFDebugInfo.h"
-#include "DWARFDefines.h"
-#include "SymbolFileDWARF.h"
-
-#include "lldb/Symbol/OCamlASTContext.h"
-
-class DWARFDebugInfoEntry;
-class DWARFDIECollection;
-
-class DWARFASTParserOCaml : public DWARFASTParser {
-public:
- DWARFASTParserOCaml(lldb_private::OCamlASTContext &ast);
-
- virtual ~DWARFASTParserOCaml();
-
- lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die);
-
- lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, lldb_private::Log *log,
- bool *type_is_new_ptr) override;
-
- lldb_private::Function *
- ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die) override;
-
- bool
- CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
- lldb_private::CompilerType &compiler_type) override {
- return false;
- }
-
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) override {
- return lldb_private::CompilerDecl();
- }
-
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
-
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
-
- std::vector<DWARFDIE> GetDIEForDeclContext(
- lldb_private::CompilerDeclContext decl_context) override {
- return {};
- }
-
-protected:
- lldb_private::OCamlASTContext &m_ast;
-};
-
-#endif // SymbolFileDWARF_DWARFASTParserOCaml_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
index a765be0b46d0..d78b9ab10f5a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -41,9 +41,13 @@ bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data,
while (data.ValidOffset(*offset_ptr)) {
dw_attr_t attr = data.GetULEB128(offset_ptr);
dw_form_t form = data.GetULEB128(offset_ptr);
+ DWARFFormValue::ValueType val;
+
+ if (form == DW_FORM_implicit_const)
+ val.value.sval = data.GetULEB128(offset_ptr);
if (attr && form)
- m_attributes.push_back(DWARFAttribute(attr, form));
+ m_attributes.push_back(DWARFAttribute(attr, form, val));
else
break;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
index b2296c455d6a..afce52558f45 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
@@ -35,20 +35,11 @@ public:
dw_form_t GetFormByIndex(uint32_t idx) const {
return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0;
}
- bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t &attr,
- dw_form_t &form) const {
- if (m_attributes.size() > idx) {
- m_attributes[idx].get(attr, form);
- return true;
- }
- attr = form = 0;
- return false;
- }
- // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked()
- void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr,
- dw_form_t &form) const {
- m_attributes[idx].get(attr, form);
+ // idx is assumed to be valid when calling GetAttrAndFormByIndex()
+ void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr,
+ DWARFFormValue &form_value) const {
+ m_attributes[idx].get(attr, form_value.FormRef(), form_value.ValueRef());
}
dw_form_t GetFormByIndexUnchecked(uint32_t idx) const {
return m_attributes[idx].get_form();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
index 2586d1f18530..dd830eb7b9dd 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -26,10 +26,10 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const {
return UINT32_MAX;
}
-void DWARFAttributes::Append(const DWARFUnit *cu,
- dw_offset_t attr_die_offset, dw_attr_t attr,
- dw_form_t form) {
- AttributeValue attr_value = {cu, attr_die_offset, {attr, form}};
+void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset,
+ dw_attr_t attr, dw_form_t form) {
+ AttributeValue attr_value = {
+ cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}};
m_infos.push_back(attr_value);
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
index db4324cf7725..2399861d7fc3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -11,15 +11,17 @@
#define SymbolFileDWARF_DWARFAttribute_h_
#include "DWARFDefines.h"
+#include "DWARFFormValue.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
class DWARFUnit;
-class DWARFFormValue;
class DWARFAttribute {
public:
- DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {}
+ DWARFAttribute(dw_attr_t attr, dw_form_t form,
+ DWARFFormValue::ValueType value)
+ : m_attr(attr), m_form(form), m_value(value) {}
void set(dw_attr_t attr, dw_form_t form) {
m_attr = attr;
@@ -29,9 +31,11 @@ public:
void set_form(dw_form_t form) { m_form = form; }
dw_attr_t get_attr() const { return m_attr; }
dw_form_t get_form() const { return m_form; }
- void get(dw_attr_t &attr, dw_form_t &form) const {
+ void get(dw_attr_t &attr, dw_form_t &form,
+ DWARFFormValue::ValueType &val) const {
attr = m_attr;
form = m_form;
+ val = m_value;
}
bool operator==(const DWARFAttribute &rhs) const {
return m_attr == rhs.m_attr && m_form == rhs.m_form;
@@ -43,6 +47,7 @@ public:
protected:
dw_attr_t m_attr;
dw_form_t m_form;
+ DWARFFormValue::ValueType m_value;
};
class DWARFAttributes {
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
index 8541f1cfe1f6..b9a7231286e3 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -34,8 +34,18 @@ DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
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);
- cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
+
+ if (cu_sp->m_version == 5) {
+ cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
+ cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
+ abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
+
+ if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
+ cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
+ } else {
+ abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
+ cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
+ }
bool length_OK =
debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
@@ -65,6 +75,23 @@ void DWARFCompileUnit::Dump(Stream *s) const {
GetNextCompileUnitOffset());
}
+uint32_t DWARFCompileUnit::GetHeaderByteSize() const {
+ if (m_version < 5)
+ return m_is_dwarf64 ? 23 : 11;
+
+ switch (m_unit_type) {
+ case llvm::dwarf::DW_UT_compile:
+ case llvm::dwarf::DW_UT_partial:
+ return 12;
+ case llvm::dwarf::DW_UT_skeleton:
+ case llvm::dwarf::DW_UT_split_compile:
+ return 20;
+ case llvm::dwarf::DW_UT_type:
+ case llvm::dwarf::DW_UT_split_type:
+ return 24;
+ }
+ llvm_unreachable("invalid UnitType.");
+}
const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
return m_dwarf->get_debug_info_data();
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index d20f31505ed4..b92a155e0335 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -35,9 +35,7 @@ public:
/// @return
/// Byte size of the compile unit header
//------------------------------------------------------------------
- uint32_t GetHeaderByteSize() const override {
- return m_is_dwarf64 ? 23 : 11;
- }
+ uint32_t GetHeaderByteSize() const override;
private:
DWARFCompileUnit(SymbolFileDWARF *dwarf2Data);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index d9754e911017..22b70b2d6852 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -166,13 +166,13 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const {
}
}
-void DWARFDIE::GetDWOContext(std::vector<CompilerContext> &context) const {
+void DWARFDIE::GetDeclContext(std::vector<CompilerContext> &context) const {
const dw_tag_t tag = Tag();
if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
return;
DWARFDIE parent = GetParent();
if (parent)
- parent.GetDWOContext(context);
+ parent.GetDeclContext(context);
switch (tag) {
case DW_TAG_module:
context.push_back(
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index ecbf4912634e..b0d06a886ac1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -90,7 +90,10 @@ public:
void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const;
- void GetDWOContext(std::vector<lldb_private::CompilerContext> &context) const;
+ /// Return this DIE's decl context as it is needed to look up types
+ /// in Clang's -gmodules debug info format.
+ void
+ GetDeclContext(std::vector<lldb_private::CompilerContext> &context) const;
//----------------------------------------------------------------------
// Getting attribute values from the DIE.
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
index ce0bfb3931d5..1f342035f135 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -10,7 +10,6 @@
#ifndef liblldb_DWARFDataExtractor_h_
#define liblldb_DWARFDataExtractor_h_
-// Other libraries and framework includes.
#include "lldb/Core/dwarf.h"
#include "lldb/Utility/DataExtractor.h"
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
index 6524cb3ce483..e7a8635f0532 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -19,7 +19,7 @@ class SymbolFileDWARF;
class DWARFDebugAranges {
protected:
- typedef lldb_private::RangeDataArray<dw_addr_t, uint32_t, dw_offset_t, 1>
+ typedef lldb_private::RangeDataVector<dw_addr_t, uint32_t, dw_offset_t>
RangeToDIE;
public:
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index d32aef6e162c..7531aeac709a 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -40,9 +40,8 @@ bool DWARFDebugInfoEntry::FastExtract(
m_offset = *offset_ptr;
m_parent_idx = 0;
m_sibling_idx = 0;
- m_empty_children = false;
const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
- assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
+ lldbassert(abbr_idx <= UINT16_MAX);
m_abbr_idx = abbr_idx;
// assert (fixed_form_sizes); // For best performance this should be
@@ -119,21 +118,33 @@ bool DWARFDebugInfoEntry::FastExtract(
break;
// 1 byte values
+ case DW_FORM_addrx1:
case DW_FORM_data1:
case DW_FORM_flag:
case DW_FORM_ref1:
+ case DW_FORM_strx1:
form_size = 1;
break;
// 2 byte values
+ case DW_FORM_addrx2:
case DW_FORM_data2:
case DW_FORM_ref2:
+ case DW_FORM_strx2:
form_size = 2;
break;
+ // 3 byte values
+ case DW_FORM_addrx3:
+ case DW_FORM_strx3:
+ form_size = 3;
+ break;
+
// 4 byte values
+ case DW_FORM_addrx4:
case DW_FORM_data4:
case DW_FORM_ref4:
+ case DW_FORM_strx4:
form_size = 4;
break;
@@ -145,11 +156,14 @@ bool DWARFDebugInfoEntry::FastExtract(
break;
// signed or unsigned LEB 128 values
+ case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
debug_info_data.Skip_LEB128(&offset);
break;
@@ -166,6 +180,10 @@ bool DWARFDebugInfoEntry::FastExtract(
debug_info_data.GetU32(&offset);
break;
+ case DW_FORM_implicit_const:
+ form_size = 0;
+ break;
+
default:
*offset_ptr = m_offset;
return false;
@@ -208,7 +226,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
m_offset = offset;
const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
- assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
+ lldbassert(abbr_idx <= UINT16_MAX);
m_abbr_idx = abbr_idx;
if (abbr_idx) {
const DWARFAbbreviationDeclaration *abbrevDecl =
@@ -225,15 +243,14 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
// Skip all data in the .debug_info for the attributes
const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i = 0; i < numAttributes; ++i) {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+ for (uint32_t i = 0; i < numAttributes; ++i) {
+ DWARFFormValue form_value(cu);
+ dw_attr_t attr;
+ abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
+ dw_form_t form = form_value.Form();
if (isCompileUnitTag &&
((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
- DWARFFormValue form_value(cu, form);
if (form_value.ExtractValue(debug_info_data, &offset)) {
if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
const_cast<DWARFUnit *>(cu)->SetBaseAddress(
@@ -279,6 +296,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
// 0 sized form
case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
form_size = 0;
break;
@@ -370,6 +388,13 @@ void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
Dump(dwarf2Data, cu, s, recurse_depth);
}
+static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges,
+ DWARFFormValue &form_value) {
+ if (form_value.Form() == DW_FORM_rnglistx)
+ return debug_ranges->GetOffset(form_value.Unsigned());
+ return form_value.Unsigned();
+}
+
//----------------------------------------------------------------------
// GetDIENamesAndRanges
//
@@ -409,14 +434,13 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
return false;
const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
bool do_offset = false;
- for (i = 0; i < numAttributes; ++i) {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
- DWARFFormValue form_value(cu, form);
+ for (uint32_t i = 0; i < numAttributes; ++i) {
+ DWARFFormValue form_value(cu);
+ dw_attr_t attr;
+ abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
+
if (form_value.ExtractValue(debug_info_data, &offset)) {
switch (attr) {
case DW_AT_low_pc:
@@ -446,20 +470,15 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
break;
case DW_AT_ranges: {
- const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
- if (debug_ranges) {
- debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges);
- // All DW_AT_ranges are relative to the base address of the compile
- // unit. We add the compile unit base address to make sure all the
- // addresses are properly fixed up.
- ranges.Slide(cu->GetBaseAddress());
- } else {
+ const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
+ if (debug_ranges)
+ debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
+ else
cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
"{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
") attribute yet DWARF has no .debug_ranges, please file a bug "
"and attach the file at the start of this error message",
m_offset, form_value.Unsigned());
- }
} break;
case DW_AT_name:
@@ -521,7 +540,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
block_length);
} else {
const DWARFDataExtractor &debug_loc_data =
- dwarf2Data->get_debug_loc_data();
+ dwarf2Data->DebugLocData();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
size_t loc_list_length = DWARFExpression::LocationListSize(
@@ -606,14 +625,13 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
// Dump all data in the .debug_info for the attributes
const uint32_t numAttributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i = 0; i < numAttributes; ++i) {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+ for (uint32_t i = 0; i < numAttributes; ++i) {
+ DWARFFormValue form_value(cu);
+ dw_attr_t attr;
+ abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
- form);
+ form_value);
}
const DWARFDebugInfoEntry *child = GetFirstChild();
@@ -663,23 +681,21 @@ void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
void DWARFDebugInfoEntry::DumpAttribute(
SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
- Stream &s, dw_attr_t attr, dw_form_t form) {
+ Stream &s, dw_attr_t attr, DWARFFormValue &form_value) {
bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);
s.Printf(" ");
s.Indent(DW_AT_value_to_name(attr));
if (show_form) {
- s.Printf("[%s", DW_FORM_value_to_name(form));
+ s.Printf("[%s", DW_FORM_value_to_name(form_value.Form()));
}
- DWARFFormValue form_value(cu, form);
-
if (!form_value.ExtractValue(debug_info_data, offset_ptr))
return;
if (show_form) {
- if (form == DW_FORM_indirect) {
+ if (form_value.Form() == DW_FORM_indirect) {
s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
}
@@ -719,7 +735,7 @@ void DWARFDebugInfoEntry::DumpAttribute(
uint64_t debug_loc_offset = form_value.Unsigned();
if (dwarf2Data) {
DWARFExpression::PrintDWARFLocationList(
- s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+ s, cu, dwarf2Data->DebugLocData(), debug_loc_offset);
}
}
} break;
@@ -740,11 +756,13 @@ void DWARFDebugInfoEntry::DumpAttribute(
} break;
case DW_AT_ranges: {
- lldb::offset_t ranges_offset = form_value.Unsigned();
+ if (!dwarf2Data)
+ break;
+ lldb::offset_t ranges_offset =
+ GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
- if (dwarf2Data)
- DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
- &ranges_offset, base_addr);
+ DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
+ &ranges_offset, base_addr);
} break;
default:
@@ -786,11 +804,11 @@ size_t DWARFDebugInfoEntry::GetAttributes(
cu->GetAddressByteSize(), cu->IsDWARF64());
const uint32_t num_attributes = abbrevDecl->NumAttributes();
- uint32_t i;
- dw_attr_t attr;
- dw_form_t form;
- for (i = 0; i < num_attributes; ++i) {
- abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
+ for (uint32_t i = 0; i < num_attributes; ++i) {
+ DWARFFormValue form_value(cu);
+ dw_attr_t attr;
+ abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
+ const dw_form_t form = form_value.Form();
// If we are tracking down DW_AT_specification or DW_AT_abstract_origin
// attributes, the depth will be non-zero. We need to omit certain
@@ -811,7 +829,6 @@ size_t DWARFDebugInfoEntry::GetAttributes(
}
if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
- DWARFFormValue form_value(cu, form);
if (form_value.ExtractValue(debug_info_data, &offset)) {
dw_offset_t die_offset = form_value.Reference();
DWARFDIE spec_die =
@@ -1055,14 +1072,11 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
bool check_specification_or_abstract_origin) const {
ranges.Clear();
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
- dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
- check_specification_or_abstract_origin);
- if (debug_ranges_offset != DW_INVALID_OFFSET) {
- DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
-
- debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
- ranges.Slide(cu->GetBaseAddress());
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
+ if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
+ debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
+ ranges);
} else if (check_hi_lo_pc) {
dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
@@ -1713,16 +1727,13 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
((function_die != NULL) || (block_die != NULL));
}
} else {
- dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
- dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
- if (debug_ranges_offset != DW_INVALID_OFFSET) {
+ DWARFFormValue form_value;
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) {
DWARFRangeList ranges;
- DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
- debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
- // All DW_AT_ranges are relative to the base address of the compile
- // unit. We add the compile unit base address to make sure all the
- // addresses are properly fixed up.
- ranges.Slide(cu->GetBaseAddress());
+ DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
+ debug_ranges->FindRanges(
+ cu, GetRangesOffset(debug_ranges, form_value), ranges);
+
if (ranges.FindEntryThatContains(address)) {
found_address = true;
// puts("***MATCH***");
@@ -1829,7 +1840,6 @@ void DWARFDebugInfoEntry::DumpDIECollection(
bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const {
return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx &&
m_sibling_idx == rhs.m_sibling_idx &&
- m_empty_children == rhs.m_empty_children &&
m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children &&
m_tag == rhs.m_tag;
}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index 97cb3046eb3e..ec19fc814fba 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -43,7 +43,6 @@ typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter;
class DWARFDeclContext;
#define DIE_SIBLING_IDX_BITSIZE 31
-#define DIE_ABBR_IDX_BITSIZE 15
class DWARFDebugInfoEntry {
public:
@@ -57,8 +56,7 @@ public:
DWARFDebugInfoEntry()
: 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) {}
+ m_has_children(false), m_abbr_idx(0), m_tag(0) {}
explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; }
bool operator==(const DWARFDebugInfoEntry &rhs) const;
@@ -178,7 +176,7 @@ public:
DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
const lldb_private::DWARFDataExtractor &debug_info_data,
lldb::offset_t *offset_ptr, lldb_private::Stream &s,
- dw_attr_t attr, dw_form_t form);
+ dw_attr_t attr, DWARFFormValue &form_value);
// This one dumps the comp unit name, objfile name and die offset for this die
// so the stream S.
void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu,
@@ -227,10 +225,10 @@ public:
// we don't need to store our child pointer, if we have a child it will
// be the next entry in the list...
DWARFDebugInfoEntry *GetFirstChild() {
- return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
+ return HasChildren() ? this + 1 : NULL;
}
const DWARFDebugInfoEntry *GetFirstChild() const {
- return (HasChildren() && !m_empty_children) ? this + 1 : NULL;
+ return HasChildren() ? this + 1 : NULL;
}
void GetDeclContextDIEs(DWARFUnit *cu,
@@ -271,10 +269,6 @@ public:
void SetParentIndex(uint32_t idx) { m_parent_idx = idx; }
- bool GetEmptyChildren() const { return m_empty_children; }
-
- void SetEmptyChildren(bool b) { m_empty_children = b; }
-
static void
DumpDIECollection(lldb_private::Stream &strm,
DWARFDebugInfoEntry::collection &die_collection);
@@ -285,13 +279,13 @@ protected:
uint32_t m_parent_idx; // How many to subtract from "this" to get the parent.
// If zero this die has no parent
uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling.
- m_empty_children : 1; // If a DIE says it had children, yet it just
- // contained a NULL tag, this will be set.
- uint32_t m_abbr_idx : DIE_ABBR_IDX_BITSIZE,
- m_has_children : 1, // Set to 1 if this DIE has children
- m_tag : 16; // A copy of the DW_TAG value so we don't
- // have to go through the compile unit
- // abbrev table
+ // If it is zero, then the DIE doesn't have children, or the
+ // DWARF claimed it had children but the DIE only contained
+ // a single NULL terminating child.
+ m_has_children : 1;
+ uint16_t m_abbr_idx;
+ uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through
+ // the compile unit abbrev table
};
#endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
index 317ea4c22c66..d9f50122bd6f 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
@@ -41,7 +41,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) {
if (line_table_sp.get() == NULL)
break;
- if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) {
+ if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) {
// Make sure we don't don't loop infinitely
if (offset <= debug_line_offset)
break;
@@ -127,7 +127,7 @@ DWARFDebugLine::DumpStatementTable(Log *log,
"--------\n",
debug_line_offset);
- if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log))
+ if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr))
return offset;
else
return debug_line_offset + 1; // Skip to next byte in .debug_line section
@@ -366,17 +366,38 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data,
void *userData) {
lldb::offset_t offset = 0;
if (debug_line_data.ValidOffset(offset)) {
- if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
+ if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr))
++offset; // Skip to next byte in .debug_line section
}
}
+namespace {
+struct EntryDescriptor {
+ dw_sleb128_t code;
+ dw_sleb128_t form;
+};
+
+static std::vector<EntryDescriptor>
+ReadDescriptors(const DWARFDataExtractor &debug_line_data,
+ lldb::offset_t *offset_ptr) {
+ std::vector<EntryDescriptor> ret;
+ uint8_t n = debug_line_data.GetU8(offset_ptr);
+ for (uint8_t i = 0; i < n; ++i) {
+ EntryDescriptor ent;
+ ent.code = debug_line_data.GetULEB128(offset_ptr);
+ ent.form = debug_line_data.GetULEB128(offset_ptr);
+ ret.push_back(ent);
+ }
+ return ret;
+}
+} // namespace
+
//----------------------------------------------------------------------
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr,
- Prologue *prologue) {
+ Prologue *prologue, DWARFUnit *dwarf_cu) {
const lldb::offset_t prologue_offset = *offset_ptr;
// DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
@@ -386,9 +407,14 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
const char *s;
prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr);
prologue->version = debug_line_data.GetU16(offset_ptr);
- if (prologue->version < 2 || prologue->version > 4)
+ if (prologue->version < 2 || prologue->version > 5)
return false;
+ if (prologue->version >= 5) {
+ prologue->address_size = debug_line_data.GetU8(offset_ptr);
+ prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr);
+ }
+
prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr);
const lldb::offset_t end_prologue_offset =
prologue->prologue_length + *offset_ptr;
@@ -410,25 +436,83 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
prologue->standard_opcode_lengths.push_back(op_len);
}
- while (*offset_ptr < end_prologue_offset) {
- s = debug_line_data.GetCStr(offset_ptr);
- if (s && s[0])
- prologue->include_directories.push_back(s);
- else
- break;
- }
+ if (prologue->version >= 5) {
+ std::vector<EntryDescriptor> dirEntryFormatV =
+ ReadDescriptors(debug_line_data, offset_ptr);
+ uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr);
+ for (int i = 0; i < dirCount; ++i) {
+ for (EntryDescriptor &ent : dirEntryFormatV) {
+ DWARFFormValue value(dwarf_cu, ent.form);
+ if (ent.code != DW_LNCT_path) {
+ if (!value.SkipValue(debug_line_data, offset_ptr))
+ return false;
+ continue;
+ }
- while (*offset_ptr < end_prologue_offset) {
- const char *name = debug_line_data.GetCStr(offset_ptr);
- if (name && name[0]) {
- FileNameEntry fileEntry;
- fileEntry.name = name;
- fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
- fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
- prologue->file_names.push_back(fileEntry);
- } else
- break;
+ if (!value.ExtractValue(debug_line_data, offset_ptr))
+ return false;
+ prologue->include_directories.push_back(value.AsCString());
+ }
+ }
+
+ std::vector<EntryDescriptor> filesEntryFormatV =
+ ReadDescriptors(debug_line_data, offset_ptr);
+ llvm::DenseSet<std::pair<uint64_t, uint64_t>> seen;
+ uint8_t n = debug_line_data.GetULEB128(offset_ptr);
+ for (int i = 0; i < n; ++i) {
+ FileNameEntry entry;
+ for (EntryDescriptor &ent : filesEntryFormatV) {
+ DWARFFormValue value(dwarf_cu, ent.form);
+ if (!value.ExtractValue(debug_line_data, offset_ptr))
+ return false;
+
+ switch (ent.code) {
+ case DW_LNCT_path:
+ entry.name = value.AsCString();
+ break;
+ case DW_LNCT_directory_index:
+ entry.dir_idx = value.Unsigned();
+ break;
+ case DW_LNCT_timestamp:
+ entry.mod_time = value.Unsigned();
+ break;
+ case DW_LNCT_size:
+ entry.length = value.Unsigned();
+ break;
+ case DW_LNCT_MD5:
+ assert(value.Unsigned() == 16);
+ std::uninitialized_copy_n(value.BlockData(), 16,
+ entry.checksum.Bytes.begin());
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (seen.insert(entry.checksum.words()).second)
+ prologue->file_names.push_back(entry);
+ }
+ } else {
+ while (*offset_ptr < end_prologue_offset) {
+ s = debug_line_data.GetCStr(offset_ptr);
+ if (s && s[0])
+ prologue->include_directories.push_back(s);
+ else
+ break;
+ }
+
+ while (*offset_ptr < end_prologue_offset) {
+ const char *name = debug_line_data.GetCStr(offset_ptr);
+ if (name && name[0]) {
+ FileNameEntry fileEntry;
+ fileEntry.name = name;
+ fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr);
+ fileEntry.length = debug_line_data.GetULEB128(offset_ptr);
+ prologue->file_names.push_back(fileEntry);
+ } else
+ break;
+ }
}
// XXX GNU as is broken for 64-Bit DWARF
@@ -445,11 +529,11 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data,
bool DWARFDebugLine::ParseSupportFiles(
const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data,
const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list,
- FileSpecList &support_files) {
+ FileSpecList &support_files, DWARFUnit *dwarf_cu) {
lldb::offset_t offset = stmt_list;
Prologue prologue;
- if (!ParsePrologue(debug_line_data, &offset, &prologue)) {
+ if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) {
Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue "
"at 0x%8.8x (parsing ended around "
"0x%8.8" PRIx64 "\n",
@@ -463,7 +547,7 @@ bool DWARFDebugLine::ParseSupportFiles(
for (uint32_t file_idx = 1;
prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) {
if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file))
- file_spec.SetFile(remapped_file, false, FileSpec::Style::native);
+ file_spec.SetFile(remapped_file, FileSpec::Style::native);
support_files.Append(file_spec);
}
return true;
@@ -478,7 +562,7 @@ bool DWARFDebugLine::ParseSupportFiles(
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- DWARFDebugLine::State::Callback callback, void *userData) {
+ DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE));
Prologue::shared_ptr prologue(new Prologue());
@@ -489,7 +573,7 @@ bool DWARFDebugLine::ParseStatementTable(
func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])",
debug_line_offset);
- if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) {
+ if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) {
if (log)
log->Error("failed to parse DWARF line table prologue");
// Restore our offset and return false to indicate failure!
@@ -775,9 +859,9 @@ static void ParseStatementTableCallback(dw_offset_t offset,
//----------------------------------------------------------------------
bool DWARFDebugLine::ParseStatementTable(
const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr,
- LineTable *line_table) {
+ LineTable *line_table, DWARFUnit *dwarf_cu) {
return ParseStatementTable(debug_line_data, offset_ptr,
- ParseStatementTableCallback, line_table);
+ ParseStatementTableCallback, line_table, dwarf_cu);
}
inline bool DWARFDebugLine::Prologue::IsValid() const {
@@ -866,7 +950,7 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx,
const lldb_private::FileSpec &comp_dir, FileSpec &file) const {
uint32_t idx = file_idx - 1; // File indexes are 1 based...
if (idx < file_names.size()) {
- file.SetFile(file_names[idx].name, false, FileSpec::Style::native);
+ file.SetFile(file_names[idx].name, FileSpec::Style::native);
if (file.IsRelative()) {
if (file_names[idx].dir_idx > 0) {
const uint32_t dir_idx = file_names[idx].dir_idx - 1;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
index 3ab15ac59028..04f72e03a2db 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
@@ -19,6 +19,9 @@
#include "DWARFDataExtractor.h"
#include "DWARFDefines.h"
+#include "llvm/Support/MD5.h"
+
+class DWARFUnit;
class SymbolFileDWARF;
//----------------------------------------------------------------------
@@ -36,6 +39,7 @@ public:
dw_sleb128_t dir_idx;
dw_sleb128_t mod_time;
dw_sleb128_t length;
+ llvm::MD5::MD5Result checksum;
};
//------------------------------------------------------------------
@@ -55,6 +59,10 @@ public:
// total_length field itself).
uint16_t
version; // Version identifier for the statement information format.
+
+ uint8_t address_size;
+ uint8_t segment_selector_size;
+
uint32_t prologue_length; // The number of bytes following the
// prologue_length field to the beginning of the
// first byte of the statement program itself.
@@ -201,14 +209,15 @@ public:
const lldb_private::DWARFDataExtractor &debug_line_data,
const lldb_private::FileSpec &cu_comp_dir,
dw_offset_t stmt_list,
- lldb_private::FileSpecList &support_files);
+ lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu);
static bool
ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, Prologue *prologue);
+ lldb::offset_t *offset_ptr, Prologue *prologue,
+ DWARFUnit *dwarf_cu = nullptr);
static bool
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
lldb::offset_t *offset_ptr, State::Callback callback,
- void *userData);
+ void *userData, DWARFUnit *dwarf_cu);
static dw_offset_t
DumpStatementTable(lldb_private::Log *log,
const lldb_private::DWARFDataExtractor &debug_line_data,
@@ -219,7 +228,8 @@ public:
const dw_offset_t line_offset, uint32_t flags);
static bool
ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data,
- lldb::offset_t *offset_ptr, LineTable *line_table);
+ lldb::offset_t *offset_ptr, LineTable *line_table,
+ DWARFUnit *dwarf_cu);
static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data,
DWARFDebugLine::State::Callback callback, void *userData);
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue,
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
index 1c31d1c42598..d79acdc5cfc4 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp
@@ -25,7 +25,7 @@ DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data,
header.m_version = debug_macro_data.GetU16(offset);
uint8_t flags = debug_macro_data.GetU8(offset);
- header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false;
+ header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0;
if (flags & DEBUG_LINE_OFFSET_MASK) {
if (header.m_offset_is_64_bit)
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 89e27efb3cc2..a0436dd7ffad 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "DWARFDebugRanges.h"
+#include "DWARFUnit.h"
#include "SymbolFileDWARF.h"
#include "lldb/Utility/Stream.h"
#include <assert.h>
@@ -29,8 +30,6 @@ static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) {
DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
-DWARFDebugRanges::~DWARFDebugRanges() {}
-
void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
DWARFRangeList range_list;
lldb::offset_t offset = 0;
@@ -112,14 +111,185 @@ void DWARFDebugRanges::Dump(Stream &s,
}
}
-bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base,
+bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
dw_offset_t debug_ranges_offset,
DWARFRangeList &range_list) const {
- dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset;
+ dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
range_map_const_iterator pos = m_range_map.find(debug_ranges_address);
if (pos != m_range_map.end()) {
range_list = pos->second;
+
+ // All DW_AT_ranges are relative to the base address of the compile
+ // unit. We add the compile unit base address to make sure all the
+ // addresses are properly fixed up.
+ range_list.Slide(cu->GetBaseAddress());
+ return true;
+ }
+ return false;
+}
+
+uint64_t DWARFDebugRanges::GetOffset(size_t Index) const {
+ lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5");
+ return 0;
+}
+
+bool DWARFDebugRngLists::ExtractRangeList(
+ const DWARFDataExtractor &data, uint8_t addrSize,
+ lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
+ rangeList.clear();
+
+ bool error = false;
+ while (!error) {
+ switch (data.GetU8(offset_ptr)) {
+ case DW_RLE_end_of_list:
+ return true;
+
+ case DW_RLE_start_length: {
+ dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
+ dw_addr_t len = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_start_length, begin, len});
+ break;
+ }
+
+ case DW_RLE_start_end: {
+ dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
+ dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize);
+ rangeList.push_back({DW_RLE_start_end, begin, end});
+ break;
+ }
+
+ case DW_RLE_base_address: {
+ dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize);
+ rangeList.push_back({DW_RLE_base_address, base, 0});
+ break;
+ }
+
+ case DW_RLE_offset_pair: {
+ dw_addr_t begin = data.GetULEB128(offset_ptr);
+ dw_addr_t end = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_offset_pair, begin, end});
+ break;
+ }
+
+ case DW_RLE_base_addressx: {
+ dw_addr_t base = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_base_addressx, base, 0});
+ break;
+ }
+
+ case DW_RLE_startx_endx: {
+ dw_addr_t start = data.GetULEB128(offset_ptr);
+ dw_addr_t end = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_startx_endx, start, end});
+ break;
+ }
+
+ case DW_RLE_startx_length: {
+ dw_addr_t start = data.GetULEB128(offset_ptr);
+ dw_addr_t length = data.GetULEB128(offset_ptr);
+ rangeList.push_back({DW_RLE_startx_length, start, length});
+ break;
+ }
+
+ default:
+ lldbassert(0 && "unknown range list entry encoding");
+ error = true;
+ }
+ }
+
+ return false;
+}
+
+static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
+ uint32_t index) {
+ uint32_t index_size = cu->GetAddressByteSize();
+ dw_offset_t addr_base = cu->GetAddrBase();
+ lldb::offset_t offset = addr_base + index * index_size;
+ return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset,
+ index_size);
+}
+
+bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
+ dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const {
+ range_list.Clear();
+ dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
+ auto pos = m_range_map.find(debug_ranges_address);
+ if (pos != m_range_map.end()) {
+ dw_addr_t BaseAddr = cu->GetBaseAddress();
+ for (const RngListEntry &E : pos->second) {
+ switch (E.encoding) {
+ case DW_RLE_start_length:
+ range_list.Append(DWARFRangeList::Entry(E.value0, E.value1));
+ break;
+ case DW_RLE_base_address:
+ BaseAddr = E.value0;
+ break;
+ case DW_RLE_start_end:
+ range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0));
+ break;
+ case DW_RLE_offset_pair:
+ range_list.Append(
+ DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0));
+ break;
+ case DW_RLE_base_addressx: {
+ BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0);
+ break;
+ }
+ case DW_RLE_startx_endx: {
+ dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+ dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1);
+ range_list.Append(DWARFRangeList::Entry(start, end - start));
+ break;
+ }
+ case DW_RLE_startx_length: {
+ dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
+ range_list.Append(DWARFRangeList::Entry(start, E.value1));
+ break;
+ }
+ default:
+ llvm_unreachable("unexpected encoding");
+ }
+ }
return true;
}
return false;
}
+
+void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
+ const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data();
+ lldb::offset_t offset = 0;
+
+ uint64_t length = data.GetU32(&offset);
+ bool isDwarf64 = (length == 0xffffffff);
+ if (isDwarf64)
+ length = data.GetU64(&offset);
+ lldb::offset_t end = offset + length;
+
+ // Check version.
+ if (data.GetU16(&offset) < 5)
+ return;
+
+ uint8_t addrSize = data.GetU8(&offset);
+
+ // We do not support non-zero segment selector size.
+ if (data.GetU8(&offset) != 0) {
+ lldbassert(0 && "not implemented");
+ return;
+ }
+
+ uint32_t offsetsAmount = data.GetU32(&offset);
+ for (uint32_t i = 0; i < offsetsAmount; ++i)
+ Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4));
+
+ lldb::offset_t listOffset = offset;
+ std::vector<RngListEntry> rangeList;
+ while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) {
+ m_range_map[listOffset] = rangeList;
+ listOffset = offset;
+ }
+}
+
+uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
+ return Offsets[Index];
+}
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index f514359e00a4..5790f448ba85 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -15,17 +15,28 @@
#include <map>
-class DWARFDebugRanges {
+class DWARFDebugRangesBase {
+public:
+ virtual ~DWARFDebugRangesBase(){};
+
+ virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0;
+ virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const = 0;
+ virtual uint64_t GetOffset(size_t Index) const = 0;
+};
+
+class DWARFDebugRanges final : public DWARFDebugRangesBase {
public:
DWARFDebugRanges();
- ~DWARFDebugRanges();
- void Extract(SymbolFileDWARF *dwarf2Data);
+
+ void Extract(SymbolFileDWARF *dwarf2Data) override;
+ bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const override;
+ uint64_t GetOffset(size_t Index) const override;
+
static void Dump(lldb_private::Stream &s,
const lldb_private::DWARFDataExtractor &debug_ranges_data,
lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
- bool FindRanges(dw_addr_t debug_ranges_base,
- dw_offset_t debug_ranges_offset,
- DWARFRangeList &range_list) const;
protected:
bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr,
@@ -37,4 +48,27 @@ protected:
range_map m_range_map;
};
+// DWARF v5 .debug_rnglists section.
+class DWARFDebugRngLists final : public DWARFDebugRangesBase {
+ struct RngListEntry {
+ uint8_t encoding;
+ uint64_t value0;
+ uint64_t value1;
+ };
+
+public:
+ void Extract(SymbolFileDWARF *dwarf2Data) override;
+ bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
+ DWARFRangeList &range_list) const override;
+ uint64_t GetOffset(size_t Index) const override;
+
+protected:
+ bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
+ uint8_t addrSize, lldb::offset_t *offset_ptr,
+ std::vector<RngListEntry> &list);
+
+ std::vector<uint64_t> Offsets;
+ std::map<dw_offset_t, std::vector<RngListEntry>> m_range_map;
+};
+
#endif // SymbolFileDWARF_DWARFDebugRanges_h_
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index 1f3c59768fdf..aff5ea64e9ce 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -10,13 +10,9 @@
#ifndef SymbolFileDWARF_DWARFDeclContext_h_
#define SymbolFileDWARF_DWARFDeclContext_h_
-// C Includes
-// C++ Includes
#include <string>
#include <vector>
-// Other libraries and framework includes
#include "lldb/Utility/ConstString.h"
-// Project includes
#include "DWARFDefines.h"
//----------------------------------------------------------------------
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
index 1d927ba3bca3..99becdbb2bc1 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp
@@ -504,9 +504,9 @@ const char *DW_MACINFO_value_to_name(uint32_t val) {
return llvmstr.data();
}
-const char *DW_CFA_value_to_name(uint32_t val) {
+const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch) {
static char invalid[100];
- llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val);
+ llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val, Arch);
if (llvmstr.empty()) {
snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val);
return invalid;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
index 926f83b3564a..0f5a885efb86 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFDefines.h
@@ -64,7 +64,7 @@ const char *DW_LNE_value_to_name(uint32_t val);
const char *DW_MACINFO_value_to_name(uint32_t val);
-const char *DW_CFA_value_to_name(uint32_t val);
+const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch);
const char *DW_GNU_EH_PE_value_to_name(uint32_t val);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
index 4fde5748d3f3..5d2a8ffdb85b 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -154,6 +154,9 @@ DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size,
DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {}
+DWARFFormValue::DWARFFormValue(const DWARFUnit *cu)
+ : m_cu(cu), m_form(0), m_value() {}
+
DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form)
: m_cu(cu), m_form(form), m_value() {}
@@ -165,6 +168,9 @@ void DWARFFormValue::Clear() {
bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
lldb::offset_t *offset_ptr) {
+ if (m_form == DW_FORM_implicit_const)
+ return true;
+
bool indirect = false;
bool is_block = false;
m_value.data = NULL;
@@ -176,8 +182,12 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
switch (m_form) {
case DW_FORM_addr:
assert(m_cu);
- m_value.value.uval = data.GetMaxU64(
- offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
+ m_value.value.uval =
+ data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu));
+ break;
+ case DW_FORM_block1:
+ m_value.value.uval = data.GetU8(offset_ptr);
+ is_block = true;
break;
case DW_FORM_block2:
m_value.value.uval = data.GetU16(offset_ptr);
@@ -187,94 +197,82 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data,
m_value.value.uval = data.GetU32(offset_ptr);
is_block = true;
break;
- case DW_FORM_data2:
- m_value.value.uval = data.GetU16(offset_ptr);
- break;
- case DW_FORM_data4:
- m_value.value.uval = data.GetU32(offset_ptr);
- break;
- case DW_FORM_data8:
- m_value.value.uval = data.GetU64(offset_ptr);
- break;
- case DW_FORM_string:
- m_value.value.cstr = data.GetCStr(offset_ptr);
+ case DW_FORM_data16:
+ m_value.value.uval = 16;
+ is_block = true;
break;
case DW_FORM_exprloc:
case DW_FORM_block:
m_value.value.uval = data.GetULEB128(offset_ptr);
is_block = true;
break;
- case DW_FORM_block1:
- m_value.value.uval = data.GetU8(offset_ptr);
- is_block = true;
- break;
- case DW_FORM_data1:
- m_value.value.uval = data.GetU8(offset_ptr);
- break;
- case DW_FORM_flag:
- m_value.value.uval = data.GetU8(offset_ptr);
+ case DW_FORM_string:
+ m_value.value.cstr = data.GetCStr(offset_ptr);
break;
case DW_FORM_sdata:
m_value.value.sval = data.GetSLEB128(offset_ptr);
break;
case DW_FORM_strp:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
assert(m_cu);
m_value.value.uval =
data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
break;
- // case DW_FORM_APPLE_db_str:
- case DW_FORM_udata:
- m_value.value.uval = data.GetULEB128(offset_ptr);
- break;
- case DW_FORM_ref_addr:
- assert(m_cu);
- ref_addr_size = 4;
- if (m_cu->GetVersion() <= 2)
- ref_addr_size = m_cu->GetAddressByteSize();
- else
- ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
- m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
- break;
+ case DW_FORM_addrx1:
+ case DW_FORM_strx1:
case DW_FORM_ref1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
m_value.value.uval = data.GetU8(offset_ptr);
break;
+ case DW_FORM_addrx2:
+ case DW_FORM_strx2:
case DW_FORM_ref2:
+ case DW_FORM_data2:
m_value.value.uval = data.GetU16(offset_ptr);
break;
+ case DW_FORM_addrx3:
+ case DW_FORM_strx3:
+ m_value.value.uval = data.GetMaxU64(offset_ptr, 3);
+ break;
+ case DW_FORM_addrx4:
+ case DW_FORM_strx4:
case DW_FORM_ref4:
+ case DW_FORM_data4:
m_value.value.uval = data.GetU32(offset_ptr);
break;
+ case DW_FORM_data8:
case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
m_value.value.uval = data.GetU64(offset_ptr);
break;
+ case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
+ case DW_FORM_strx:
+ case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_addr_index:
m_value.value.uval = data.GetULEB128(offset_ptr);
break;
+ case DW_FORM_ref_addr:
+ assert(m_cu);
+ if (m_cu->GetVersion() <= 2)
+ ref_addr_size = m_cu->GetAddressByteSize();
+ else
+ ref_addr_size = m_cu->IsDWARF64() ? 8 : 4;
+ m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size);
+ break;
case DW_FORM_indirect:
m_form = data.GetULEB128(offset_ptr);
indirect = true;
break;
-
- case DW_FORM_sec_offset:
- assert(m_cu);
- m_value.value.uval =
- data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4);
- break;
case DW_FORM_flag_present:
m_value.value.uval = 1;
break;
- case DW_FORM_ref_sig8:
- m_value.value.uval = data.GetU64(offset_ptr);
- break;
- case DW_FORM_GNU_str_index:
- m_value.value.uval = data.GetULEB128(offset_ptr);
- break;
- case DW_FORM_GNU_addr_index:
- m_value.value.uval = data.GetULEB128(offset_ptr);
- break;
default:
return false;
- break;
}
} while (indirect);
@@ -346,49 +344,65 @@ bool DWARFFormValue::SkipValue(dw_form_t form,
// 0 bytes values (implied from DW_FORM)
case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
return true;
- // 1 byte values
- case DW_FORM_data1:
- case DW_FORM_flag:
- case DW_FORM_ref1:
- *offset_ptr += 1;
- return true;
+ // 1 byte values
+ case DW_FORM_addrx1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ case DW_FORM_strx1:
+ *offset_ptr += 1;
+ return true;
- // 2 byte values
- case DW_FORM_data2:
- case DW_FORM_ref2:
- *offset_ptr += 2;
- return true;
+ // 2 byte values
+ case DW_FORM_addrx2:
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ *offset_ptr += 2;
+ return true;
- // 32 bit for DWARF 32, 64 for DWARF 64
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- assert(cu);
- *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
- return true;
+ // 3 byte values
+ case DW_FORM_addrx3:
+ case DW_FORM_strx3:
+ *offset_ptr += 3;
+ return true;
- // 4 byte values
- case DW_FORM_data4:
- case DW_FORM_ref4:
- *offset_ptr += 4;
- return true;
+ // 32 bit for DWARF 32, 64 for DWARF 64
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ assert(cu);
+ *offset_ptr += (cu->IsDWARF64() ? 8 : 4);
+ return true;
- // 8 byte values
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- *offset_ptr += 8;
- return true;
+ // 4 byte values
+ case DW_FORM_addrx4:
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_strx4:
+ *offset_ptr += 4;
+ return true;
- // signed or unsigned LEB 128 values
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- debug_info_data.Skip_LEB128(offset_ptr);
- return true;
+ // 8 byte values
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ *offset_ptr += 8;
+ return true;
+
+ // signed or unsigned LEB 128 values
+ case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_strx:
+ debug_info_data.Skip_LEB128(offset_ptr);
+ return true;
case DW_FORM_indirect: {
dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr);
@@ -546,6 +560,26 @@ const char *DWARFFormValue::AsCString() const {
index_size);
return symbol_file->get_debug_str_data().PeekCStr(str_offset);
}
+
+ if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 ||
+ m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 ||
+ m_form == DW_FORM_strx4) {
+
+ // The same code as above.
+ if (!symbol_file)
+ return nullptr;
+
+ uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4;
+ lldb::offset_t offset =
+ m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize;
+ dw_offset_t strOffset =
+ symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize);
+ return symbol_file->get_debug_str_data().PeekCStr(strOffset);
+ }
+
+ if (m_form == DW_FORM_line_strp)
+ return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval);
+
return nullptr;
}
@@ -556,7 +590,9 @@ dw_addr_t DWARFFormValue::Address() const {
return Unsigned();
assert(m_cu);
- assert(m_form == DW_FORM_GNU_addr_index);
+ assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx ||
+ m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 ||
+ m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4);
if (!symbol_file)
return 0;
@@ -568,7 +604,7 @@ dw_addr_t DWARFFormValue::Address() const {
}
uint64_t DWARFFormValue::Reference() const {
- uint64_t die_offset = m_value.value.uval;
+ uint64_t value = m_value.value.uval;
switch (m_form) {
case DW_FORM_ref1:
case DW_FORM_ref2:
@@ -577,32 +613,36 @@ uint64_t DWARFFormValue::Reference() const {
case DW_FORM_ref_udata:
assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile
// unit relative or we will get this wrong
- die_offset += m_cu->GetOffset();
- break;
+ return value + m_cu->GetOffset();
+
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_ref_alt:
+ return value;
default:
- break;
+ return DW_INVALID_OFFSET;
}
-
- return die_offset;
}
uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
- uint64_t die_offset = m_value.value.uval;
+ uint64_t value = m_value.value.uval;
switch (m_form) {
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
- die_offset += base_offset;
- break;
+ return value + base_offset;
+
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_GNU_ref_alt:
+ return value;
default:
- break;
+ return DW_INVALID_OFFSET;
}
-
- return die_offset;
}
const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
@@ -729,6 +769,8 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value,
bool DWARFFormValue::FormIsSupported(dw_form_t form) {
switch (form) {
case DW_FORM_addr:
+ case DW_FORM_addrx:
+ case DW_FORM_rnglistx:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_data2:
@@ -741,6 +783,11 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
case DW_FORM_flag:
case DW_FORM_sdata:
case DW_FORM_strp:
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
case DW_FORM_udata:
case DW_FORM_ref_addr:
case DW_FORM_ref1:
@@ -755,6 +802,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) {
case DW_FORM_ref_sig8:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_addr_index:
+ case DW_FORM_implicit_const:
return true;
default:
break;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
index ef1a693b37c9..0890f0c1bfc5 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -11,9 +11,10 @@
#define SymbolFileDWARF_DWARFFormValue_h_
#include "DWARFDataExtractor.h"
-#include <stddef.h> // for NULL
+#include <stddef.h>
class DWARFUnit;
+class SymbolFileDWARF;
class DWARFFormValue {
public:
@@ -55,12 +56,17 @@ public:
};
DWARFFormValue();
+ DWARFFormValue(const DWARFUnit *cu);
DWARFFormValue(const DWARFUnit *cu, dw_form_t form);
const DWARFUnit *GetCompileUnit() const { return m_cu; }
void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; }
dw_form_t Form() const { return m_form; }
+ dw_form_t& FormRef() { return m_form; }
void SetForm(dw_form_t form) { m_form = form; }
const ValueType &Value() const { return m_value; }
+ ValueType &ValueRef() { return m_value; }
+ void SetValue(const ValueType &val) { m_value = val; }
+
void Dump(lldb_private::Stream &s) const;
bool ExtractValue(const lldb_private::DWARFDataExtractor &data,
lldb::offset_t *offset_ptr);
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index f44b2bb97b2b..7afc71bc24f0 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -191,13 +191,6 @@ void DWARFUnit::ExtractDIEsRWLocked() {
IsDWARF64());
while (offset < next_cu_offset &&
die.FastExtract(data, this, fixed_form_sizes, &offset)) {
- // if (log)
- // log->Printf("0x%8.8x: %*.*s%s%s",
- // die.GetOffset(),
- // depth * 2, depth * 2, "",
- // DW_TAG_value_to_name (die.Tag()),
- // die.HasChildren() ? " *" : "");
-
const bool null_die = die.IsNULL();
if (depth == 0) {
assert(m_die_array.empty() && "Compile unit DIE already added");
@@ -223,7 +216,7 @@ void DWARFUnit::ExtractDIEsRWLocked() {
// the list (saves up to 25% in C++ code), we need a way to let the
// DIE know that it actually doesn't have children.
if (!m_die_array.empty())
- m_die_array.back().SetEmptyChildren(true);
+ m_die_array.back().SetHasChildren(false);
}
} else {
die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]);
@@ -244,9 +237,6 @@ void DWARFUnit::ExtractDIEsRWLocked() {
if (depth > 0)
--depth;
- if (depth == 0)
- break; // We are done with this compile unit!
-
prev_die_had_children = false;
} else {
die_index_stack.back() = m_die_array.size() - 1;
@@ -258,10 +248,17 @@ void DWARFUnit::ExtractDIEsRWLocked() {
}
prev_die_had_children = die_has_children;
}
+
+ if (depth == 0)
+ break; // We are done with this compile unit!
}
if (!m_die_array.empty()) {
- lldbassert(!m_first_die || m_first_die == m_die_array.front());
+ if (m_first_die) {
+ // Only needed for the assertion.
+ m_first_die.SetHasChildren(m_die_array.front().HasChildren());
+ lldbassert(m_first_die == m_die_array.front());
+ }
m_first_die = m_die_array.front();
}
@@ -301,8 +298,46 @@ void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const {
}
}
+// This is used when a split dwarf is enabled.
+// A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute
+// that points to the first string offset of the CU contribution to the
+// .debug_str_offsets. At the same time, the corresponding split debug unit also
+// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and
+// for that case, we should find the offset (skip the section header).
+static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
+ lldb::offset_t baseOffset = 0;
+
+ const DWARFDataExtractor &strOffsets =
+ dwo_cu->GetSymbolFileDWARF()->get_debug_str_offsets_data();
+ uint64_t length = strOffsets.GetU32(&baseOffset);
+ if (length == 0xffffffff)
+ length = strOffsets.GetU64(&baseOffset);
+
+ // Check version.
+ if (strOffsets.GetU16(&baseOffset) < 5)
+ return;
+
+ // Skip padding.
+ baseOffset += 2;
+
+ dwo_cu->SetStrOffsetsBase(baseOffset);
+}
+
// m_die_array_mutex must be already held as read/write.
void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
+ dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf, this, DW_AT_addr_base, LLDB_INVALID_ADDRESS);
+ if (addr_base != LLDB_INVALID_ADDRESS)
+ SetAddrBase(addr_base);
+
+ dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS);
+ if (ranges_base != LLDB_INVALID_ADDRESS)
+ SetRangesBase(ranges_base);
+
+ SetStrOffsetsBase(cu_die.GetAttributeValueAsUnsigned(
+ m_dwarf, this, DW_AT_str_offsets_base, 0));
+
uint64_t base_addr = cu_die.GetAttributeValueAsAddress(
m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
if (base_addr == LLDB_INVALID_ADDRESS)
@@ -333,11 +368,25 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
m_dwo_symbol_file = std::move(dwo_symbol_file);
- dw_addr_t addr_base =
- cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0);
- dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
- m_dwarf, this, DW_AT_GNU_ranges_base, 0);
- dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset);
+ // Here for DWO CU we want to use the address base set in the skeleton unit
+ // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base
+ // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_*
+ // attributes which were applicable to the DWO units. The corresponding
+ // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main
+ // unit in contrast.
+ if (addr_base == LLDB_INVALID_ADDRESS)
+ addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
+ DW_AT_GNU_addr_base, 0);
+ dwo_cu->SetAddrBase(addr_base);
+
+ if (ranges_base == LLDB_INVALID_ADDRESS)
+ ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this,
+ DW_AT_GNU_ranges_base, 0);
+ dwo_cu->SetRangesBase(ranges_base);
+
+ dwo_cu->SetBaseObjOffset(m_offset);
+
+ SetDwoStrOffsetsBase(dwo_cu);
}
DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) {
@@ -395,14 +444,20 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
}
-void DWARFUnit::SetAddrBase(dw_addr_t addr_base,
- dw_addr_t ranges_base,
- dw_offset_t base_obj_offset) {
- m_addr_base = addr_base;
+void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; }
+
+void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
m_ranges_base = ranges_base;
+}
+
+void DWARFUnit::SetBaseObjOffset(dw_offset_t base_obj_offset) {
m_base_obj_offset = base_obj_offset;
}
+void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
+ m_str_offsets_base = str_offsets_base;
+}
+
// It may be called only with m_die_array_mutex held R/W.
void DWARFUnit::ClearDIEsRWLocked() {
m_die_array.clear();
@@ -586,9 +641,7 @@ void DWARFUnit::SetUserData(void *d) {
}
bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
- if (GetProducer() == eProducerLLVMGCC)
- return false;
- return true;
+ return GetProducer() != eProducerLLVMGCC;
}
bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() {
@@ -600,11 +653,8 @@ bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() {
bool DWARFUnit::Supports_unnamed_objc_bitfields() {
if (GetProducer() == eProducerClang) {
const uint32_t major_version = GetProducerVersionMajor();
- if (major_version > 425 ||
- (major_version == 425 && GetProducerVersionUpdate() >= 13))
- return true;
- else
- return false;
+ return major_version > 425 ||
+ (major_version == 425 && GetProducerVersionUpdate() >= 13);
}
return true; // Assume all other compilers didn't have incorrect ObjC bitfield
// info
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 3cc24d4202b8..178c894686ee 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -111,8 +111,11 @@ public:
dw_addr_t GetBaseAddress() const { return m_base_addr; }
dw_addr_t GetAddrBase() const { return m_addr_base; }
dw_addr_t GetRangesBase() const { return m_ranges_base; }
- void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base,
- dw_offset_t base_obj_offset);
+ dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
+ void SetAddrBase(dw_addr_t addr_base);
+ void SetRangesBase(dw_addr_t ranges_base);
+ void SetBaseObjOffset(dw_offset_t base_obj_offset);
+ void SetStrOffsetsBase(dw_offset_t str_offsets_base);
void BuildAddressRangeTable(SymbolFileDWARF *dwarf,
DWARFDebugAranges *debug_aranges);
@@ -202,6 +205,8 @@ protected:
dw_offset_t m_length = 0;
uint16_t m_version = 0;
uint8_t m_addr_size = 0;
+ uint8_t m_unit_type = 0;
+ uint64_t m_dwo_id = 0;
DWARFProducer m_producer = eProducerInvalid;
uint32_t m_producer_version_major = 0;
uint32_t m_producer_version_minor = 0;
@@ -214,7 +219,7 @@ protected:
// 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;
-
+ dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
// Offset of the initial length field.
dw_offset_t m_offset;
diff --git a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 614ff470d161..c043272f8a3e 100644
--- a/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -225,7 +225,8 @@ void DebugNamesDWARFIndex::GetFunctions(
const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask,
std::vector<DWARFDIE> &dies) {
- m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies);
+ std::vector<DWARFDIE> v;
+ m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v);
for (const DebugNames::Entry &entry :
m_debug_names_up->equal_range(name.GetStringRef())) {
@@ -235,8 +236,13 @@ void DebugNamesDWARFIndex::GetFunctions(
if (DIERef ref = ToDIERef(entry))
ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx,
- name_type_mask, dies);
+ name_type_mask, v);
}
+
+ std::set<DWARFDebugInfoEntry *> seen;
+ for (DWARFDIE die : v)
+ if (seen.insert(die.GetDIE()).second)
+ dies.push_back(die);
}
void DebugNamesDWARFIndex::GetFunctions(const RegularExpression &regex,
diff --git a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
index 36211a08557e..f83ba6663dfc 100644
--- a/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -279,7 +279,9 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data,
switch (header_data.atoms[i].type) {
case eAtomTypeDIEOffset: // DIE offset, check form for encoding
hash_data.offset =
- (dw_offset_t)form_value.Reference(header_data.die_base_offset);
+ DWARFFormValue::IsDataForm(form_value.Form())
+ ? form_value.Unsigned()
+ : form_value.Reference(header_data.die_base_offset);
break;
case eAtomTypeTag: // DW_TAG value for the DIE
diff --git a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
index 0293fbd7c495..038e9b8c2b08 100644
--- a/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h
@@ -10,10 +10,6 @@
#ifndef SymbolFileDWARF_LogChannelDWARF_h_
#define SymbolFileDWARF_LogChannelDWARF_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/Log.h"
#define DWARF_LOG_DEBUG_INFO (1u << 1)
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ac320ac52b08..2a0a89f0b25a 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,7 +9,6 @@
#include "SymbolFileDWARF.h"
-// Other libraries and framework includes
#include "llvm/Support/Casting.h"
#include "llvm/Support/Threading.h"
@@ -17,12 +16,12 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Scalar.h"
#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/Scalar.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
@@ -111,17 +110,14 @@ using namespace lldb_private;
namespace {
-PropertyDefinition g_properties[] = {
+static constexpr PropertyDefinition g_properties[] = {
{"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr,
- nullptr,
+ {},
"If the DW_AT_comp_dir matches any of these paths the symbolic "
"links will be resolved at DWARF parse time."},
- {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr,
- nullptr,
+ {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {},
"Ignore indexes present in the object files and always index DWARF "
- "manually."},
- {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr},
-};
+ "manually."}};
enum {
ePropertySymLinkPaths,
@@ -200,7 +196,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) {
bool is_symlink = false;
// Always normalize our compile unit directory to get rid of redundant
// slashes and other path anomalies before we use it for path prepending
- FileSpec local_spec(local_path, false);
+ FileSpec local_spec(local_path);
const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths();
for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i)
is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i),
@@ -215,7 +211,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) {
return local_spec;
FileSpec resolved_symlink;
- const auto error = FileSystem::Readlink(local_spec, resolved_symlink);
+ const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink);
if (error.Success())
return resolved_symlink;
@@ -263,6 +259,9 @@ SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) {
}
TypeList *SymbolFileDWARF::GetTypeList() {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile)
return debug_map_symfile->GetTypeList();
@@ -341,9 +340,10 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset,
}
size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope,
- uint32_t type_mask, TypeList &type_list)
+ TypeClass type_mask, TypeList &type_list)
{
+ ASSERT_MODULE_LOCK(this);
TypeSet type_set;
CompileUnit *comp_unit = NULL;
@@ -413,9 +413,9 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile)
m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(),
m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(),
m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(),
- m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(),
- m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(),
- m_line(), m_fetched_external_modules(false),
+ m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(),
+ m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(),
+ m_abbr(), m_info(), m_line(), m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
m_unique_ast_type_map() {}
@@ -494,7 +494,7 @@ void SymbolFileDWARF::InitializeObject() {
}
bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
- return version == 2 || version == 3 || version == 4;
+ return version >= 2 && version <= 5;
}
uint32_t SymbolFileDWARF::CalculateAbilities() {
@@ -645,19 +645,40 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str);
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro);
}
+const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() {
+ const DWARFDataExtractor &debugLocData = get_debug_loc_data();
+ if (debugLocData.GetByteSize() > 0)
+ return debugLocData;
+ return get_debug_loclists_data();
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugLocLists,
+ m_data_debug_loclists);
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugRanges,
m_data_debug_ranges);
}
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugRngLists,
+ m_data_debug_rnglists);
+}
+
const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() {
return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str);
}
@@ -747,21 +768,24 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) {
return NULL;
}
-DWARFDebugRanges *SymbolFileDWARF::DebugRanges() {
+DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() {
if (m_ranges.get() == NULL) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
static_cast<void *>(this));
- if (get_debug_ranges_data().GetByteSize() > 0) {
+
+ if (get_debug_ranges_data().GetByteSize() > 0)
m_ranges.reset(new DWARFDebugRanges());
- if (m_ranges.get())
- m_ranges->Extract(this);
- }
+ else if (get_debug_rnglists_data().GetByteSize() > 0)
+ m_ranges.reset(new DWARFDebugRngLists());
+
+ if (m_ranges.get())
+ m_ranges->Extract(this);
}
return m_ranges.get();
}
-const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const {
+const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const {
return m_ranges.get();
}
@@ -786,7 +810,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
if (module_sp) {
const DWARFDIE cu_die = dwarf_cu->DIE();
if (cu_die) {
- FileSpec cu_file_spec{cu_die.GetName(), false};
+ FileSpec cu_file_spec(cu_die.GetName());
if (cu_file_spec) {
// If we have a full path to the compile unit, we don't need to
// resolve the file. This can be expensive e.g. when the source
@@ -801,8 +825,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
std::string remapped_file;
if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
remapped_file))
- cu_file_spec.SetFile(remapped_file, false,
- FileSpec::Style::native);
+ cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
}
LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
@@ -851,6 +874,7 @@ uint32_t SymbolFileDWARF::GetNumCompileUnits() {
}
CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
+ ASSERT_MODULE_LOCK(this);
CompUnitSP cu_sp;
DWARFDebugInfo *info = DebugInfo();
if (info) {
@@ -861,8 +885,9 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
return cu_sp;
}
-Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc,
- const DWARFDIE &die) {
+Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
+ const DWARFDIE &die) {
+ ASSERT_MODULE_LOCK(this);
if (die.IsValid()) {
TypeSystem *type_system =
GetTypeSystemForLanguage(die.GetCU()->GetLanguageType());
@@ -870,7 +895,7 @@ Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc,
if (type_system) {
DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
if (dwarf_ast)
- return dwarf_ast->ParseFunctionFromDWARF(sc, die);
+ return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
}
}
return nullptr;
@@ -884,20 +909,19 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) {
// This is a normal DWARF file, no address fixups need to happen
return true;
}
-lldb::LanguageType
-SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) {
- assert(sc.comp_unit);
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetLanguageType();
else
return eLanguageTypeUnknown;
}
-size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
- assert(sc.comp_unit);
+size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
size_t functions_added = 0;
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
DWARFDIECollection function_dies;
const size_t num_functions =
@@ -905,8 +929,8 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
size_t func_idx;
for (func_idx = 0; func_idx < num_functions; ++func_idx) {
DWARFDIE die = function_dies.GetDIEAtIndex(func_idx);
- if (sc.comp_unit->FindFunctionByUID(die.GetID()).get() == NULL) {
- if (ParseCompileUnitFunction(sc, die))
+ if (comp_unit.FindFunctionByUID(die.GetID()).get() == NULL) {
+ if (ParseFunction(comp_unit, die))
++functions_added;
}
}
@@ -915,10 +939,10 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) {
return functions_added;
}
-bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
- const SymbolContext &sc, FileSpecList &support_files) {
- assert(sc.comp_unit);
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) {
+ ASSERT_MODULE_LOCK(this);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly();
@@ -930,19 +954,19 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles(
if (stmt_list != DW_INVALID_OFFSET) {
// All file indexes in DWARF are one based and a file of index zero is
// supposed to be the compile unit itself.
- support_files.Append(*sc.comp_unit);
+ support_files.Append(comp_unit);
return DWARFDebugLine::ParseSupportFiles(
- sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir,
- stmt_list, support_files);
+ comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir,
+ stmt_list, support_files, dwarf_cu);
}
}
}
return false;
}
-bool SymbolFileDWARF::ParseCompileUnitIsOptimized(
- const lldb_private::SymbolContext &sc) {
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu)
return dwarf_cu->GetIsOptimized();
return false;
@@ -951,6 +975,7 @@ bool SymbolFileDWARF::ParseCompileUnitIsOptimized(
bool SymbolFileDWARF::ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) {
+ ASSERT_MODULE_LOCK(this);
assert(sc.comp_unit);
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
if (dwarf_cu) {
@@ -1027,12 +1052,12 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset,
}
}
-bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
- assert(sc.comp_unit);
- if (sc.comp_unit->GetLineTable() != NULL)
+bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
+ if (comp_unit.GetLineTable() != NULL)
return true;
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly();
if (dwarf_cu_die) {
@@ -1040,7 +1065,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list,
DW_INVALID_OFFSET);
if (cu_line_offset != DW_INVALID_OFFSET) {
- std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
+ std::unique_ptr<LineTable> line_table_ap(new LineTable(&comp_unit));
if (line_table_ap.get()) {
ParseDWARFLineTableCallbackInfo info;
info.line_table = line_table_ap.get();
@@ -1053,9 +1078,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
* #0
* for MIPS. Use ArchSpec to clear the bit #0.
*/
- ArchSpec arch;
- GetObjectFile()->GetArchitecture(arch);
- switch (arch.GetMachine()) {
+ switch (GetObjectFile()->GetArchitecture().GetMachine()) {
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
@@ -1070,17 +1093,17 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) {
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset,
ParseDWARFLineTableCallback,
- &info);
+ &info, dwarf_cu);
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
// We have an object file that has a line table with addresses that
// are not linked. We need to link the line table and convert the
// addresses that are relative to the .o file into addresses for
// the main executable.
- sc.comp_unit->SetLineTable(
+ comp_unit.SetLineTable(
debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get()));
} else {
- sc.comp_unit->SetLineTable(line_table_ap.release());
+ comp_unit.SetLineTable(line_table_ap.release());
return true;
}
}
@@ -1112,10 +1135,10 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) {
return debug_macros_sp;
}
-bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
- assert(sc.comp_unit);
+bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu == nullptr)
return false;
@@ -1131,16 +1154,14 @@ bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
if (sect_offset == DW_INVALID_OFFSET)
return false;
- sc.comp_unit->SetDebugMacros(ParseDebugMacros(&sect_offset));
+ comp_unit.SetDebugMacros(ParseDebugMacros(&sect_offset));
return true;
}
-size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
- Block *parent_block,
- const DWARFDIE &orig_die,
- addr_t subprogram_low_pc,
- uint32_t depth) {
+size_t SymbolFileDWARF::ParseBlocksRecursive(
+ lldb_private::CompileUnit &comp_unit, Block *parent_block,
+ const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth) {
size_t blocks_added = 0;
DWARFDIE die = orig_die;
while (die) {
@@ -1219,13 +1240,13 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
std::unique_ptr<Declaration> decl_ap;
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
decl_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
+ comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
decl_line, decl_column));
std::unique_ptr<Declaration> call_ap;
if (call_file != 0 || call_line != 0 || call_column != 0)
call_ap.reset(new Declaration(
- sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
+ comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file),
call_line, call_column));
block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(),
@@ -1235,8 +1256,9 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc,
++blocks_added;
if (die.HasChildren()) {
- blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(),
- subprogram_low_pc, depth + 1);
+ blocks_added +=
+ ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(),
+ subprogram_low_pc, depth + 1);
}
}
} break;
@@ -1292,6 +1314,9 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) {
}
SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
// must make sure we use the correct DWARF file when resolving things. On
// MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
@@ -1308,6 +1333,9 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) {
DWARFDIE
SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
// must make sure we use the correct DWARF file when resolving things. On
// MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
@@ -1322,6 +1350,9 @@ SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) {
}
CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
// SymbolFileDWARF::GetDIEFromUID() for details.
@@ -1333,6 +1364,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
// SymbolFileDWARF::GetDIEFromUID() for details.
@@ -1344,6 +1378,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) {
CompilerDeclContext
SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
// SymbolFileDWARF::GetDIEFromUID() for details.
@@ -1354,6 +1391,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
}
Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
+ // This method can be called without going through the symbol vendor so we
+ // need to lock the module.
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
// Anytime we have a lldb::user_id_t, we must get the DIE by calling
// SymbolFileDWARF::GetDIEFromUID(). See comments inside the
// SymbolFileDWARF::GetDIEFromUID() for details.
@@ -1364,6 +1404,17 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
return nullptr;
}
+llvm::Optional<SymbolFile::ArrayInfo>
+SymbolFileDWARF::GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ DWARFDIE type_die = GetDIEFromUID(type_uid);
+ if (type_die)
+ return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx);
+ else
+ return llvm::None;
+}
+
Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {
return ResolveType(GetDIE(die_ref), true);
}
@@ -1429,8 +1480,7 @@ bool SymbolFileDWARF::HasForwardDeclForClangType(
}
bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
- std::lock_guard<std::recursive_mutex> guard(
- GetObjectFile()->GetModule()->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ClangASTContext *clang_type_system =
llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem());
@@ -1525,7 +1575,7 @@ bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, die);
+ sc.function = ParseFunction(*sc.comp_unit, die);
if (sc.function) {
sc.module_sp = sc.function->CalculateSymbolContextModule();
@@ -1578,18 +1628,20 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
return dwo_symfile;
}
- FileSpec dwo_file(dwo_name, true);
+ FileSpec dwo_file(dwo_name);
+ FileSystem::Instance().Resolve(dwo_file);
if (dwo_file.IsRelative()) {
const char *comp_dir = cu_die.GetAttributeValueAsString(
this, &dwarf_cu, DW_AT_comp_dir, nullptr);
if (!comp_dir)
return nullptr;
- dwo_file.SetFile(comp_dir, true, FileSpec::Style::native);
+ dwo_file.SetFile(comp_dir, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dwo_file);
dwo_file.AppendPathComponent(dwo_name);
}
- if (!dwo_file.Exists())
+ if (!FileSystem::Instance().Exists(dwo_file))
return nullptr;
const lldb::offset_t file_offset = 0;
@@ -1597,7 +1649,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
lldb::offset_t dwo_file_data_offset = 0;
ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(
GetObjectFile()->GetModule(), &dwo_file, file_offset,
- dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset);
+ FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp,
+ dwo_file_data_offset);
if (dwo_obj_file == nullptr)
return nullptr;
@@ -1616,7 +1669,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
- if (die && die.HasChildren() == false) {
+ if (die && !die.HasChildren()) {
const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr);
if (name) {
@@ -1628,14 +1681,15 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
if (dwo_path) {
ModuleSpec dwo_module_spec;
- dwo_module_spec.GetFileSpec().SetFile(dwo_path, false,
+ dwo_module_spec.GetFileSpec().SetFile(dwo_path,
FileSpec::Style::native);
if (dwo_module_spec.GetFileSpec().IsRelative()) {
const char *comp_dir =
die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr);
if (comp_dir) {
- dwo_module_spec.GetFileSpec().SetFile(comp_dir, true,
+ dwo_module_spec.GetFileSpec().SetFile(comp_dir,
FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec());
dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path);
}
}
@@ -1726,7 +1780,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() {
}
uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
- uint32_t resolve_scope,
+ SymbolContextItem resolve_scope,
SymbolContext &sc) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
@@ -1784,7 +1838,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
sc.function =
sc.comp_unit->FindFunctionByUID(function_die.GetID()).get();
if (sc.function == NULL)
- sc.function = ParseCompileUnitFunction(sc, function_die);
+ sc.function = ParseFunction(*sc.comp_unit, function_die);
if (sc.function && (resolve_scope & eSymbolContextBlock))
block_die = function_die.LookupDeepestBlock(file_vm_addr);
@@ -1860,7 +1914,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr,
uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
uint32_t line,
bool check_inlines,
- uint32_t resolve_scope,
+ SymbolContextItem resolve_scope,
SymbolContextList &sc_list) {
const uint32_t prev_size = sc_list.GetSize();
if (resolve_scope & eSymbolContextCompUnit) {
@@ -1925,7 +1979,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
.get();
if (sc.function == NULL)
sc.function =
- ParseCompileUnitFunction(sc, function_die);
+ ParseFunction(*sc.comp_unit, function_die);
if (sc.function &&
(resolve_scope & eSymbolContextBlock))
@@ -1975,11 +2029,17 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
}
void SymbolFileDWARF::PreloadSymbols() {
- std::lock_guard<std::recursive_mutex> guard(
- GetObjectFile()->GetModule()->GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
m_index->Preload();
}
+std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const {
+ lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
+ if (module_sp)
+ return module_sp->GetMutex();
+ return GetObjectFile()->GetModule()->GetMutex();
+}
+
bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx) {
if (decl_ctx == nullptr || !decl_ctx->IsValid()) {
@@ -2195,7 +2255,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
sc.block = function_block.FindBlockByID(inlined_die.GetID());
if (sc.block == NULL)
sc.block = function_block.FindBlockByID(inlined_die.GetOffset());
- if (sc.block == NULL || sc.block->GetStartAddress(addr) == false)
+ if (sc.block == NULL || !sc.block->GetStartAddress(addr))
addr.Clear();
} else {
sc.block = NULL;
@@ -2231,11 +2291,10 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx,
return false;
}
-uint32_t
-SymbolFileDWARF::FindFunctions(const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines,
- bool append, SymbolContextList &sc_list) {
+uint32_t SymbolFileDWARF::FindFunctions(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask, bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')",
name.AsCString());
@@ -2378,9 +2437,8 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
uint32_t SymbolFileDWARF::FindTypes(
- const SymbolContext &sc, const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
// If we aren't appending the results to this list, then clear the list
@@ -2469,8 +2527,8 @@ uint32_t SymbolFileDWARF::FindTypes(
SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor();
if (sym_vendor) {
const uint32_t num_external_matches =
- sym_vendor->FindTypes(sc, name, parent_decl_ctx, append,
- max_matches, searched_symbol_files, types);
+ sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types);
if (num_external_matches)
return num_external_matches;
}
@@ -2506,7 +2564,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
if (die) {
std::vector<CompilerContext> die_context;
- die.GetDWOContext(die_context);
+ die.GetDeclContext(die_context);
if (die_context != context)
continue;
@@ -2528,7 +2586,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector<CompilerContext> &context,
}
CompilerDeclContext
-SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name,
+SymbolFileDWARF::FindNamespace(const ConstString &name,
const CompilerDeclContext *parent_decl_ctx) {
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
@@ -3065,39 +3123,36 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc,
return types_added;
}
-size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) {
- assert(sc.comp_unit && sc.function);
+size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
+ ASSERT_MODULE_LOCK(this);
+ CompileUnit *comp_unit = func.GetCompileUnit();
+ lldbassert(comp_unit);
+
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);
+ if (!dwarf_cu)
+ return 0;
+
size_t functions_added = 0;
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
- if (dwarf_cu) {
- const dw_offset_t function_die_offset = sc.function->GetID();
- DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset);
- if (function_die) {
- ParseFunctionBlocks(sc, &sc.function->GetBlock(false), function_die,
- LLDB_INVALID_ADDRESS, 0);
- }
+ const dw_offset_t function_die_offset = func.GetID();
+ DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset);
+ if (function_die) {
+ ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die,
+ LLDB_INVALID_ADDRESS, 0);
}
return functions_added;
}
-size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) {
- // At least a compile unit must be valid
- assert(sc.comp_unit);
+size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
+ ASSERT_MODULE_LOCK(this);
size_t types_added = 0;
- DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+ DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
if (dwarf_cu) {
- if (sc.function) {
- dw_offset_t function_die_offset = sc.function->GetID();
- DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset);
- if (func_die && func_die.HasChildren()) {
- types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true);
- }
- } else {
- DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
- if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
- types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
- }
+ DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
+ if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
+ SymbolContext sc;
+ sc.comp_unit = &comp_unit;
+ types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true);
}
}
@@ -3105,6 +3160,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) {
}
size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
+ ASSERT_MODULE_LOCK(this);
if (sc.comp_unit != NULL) {
DWARFDebugInfo *info = DebugInfo();
if (info == NULL)
@@ -3298,7 +3354,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
uint32_t block_length = form_value.Unsigned();
location.CopyOpcodeData(module, data, block_offset, block_length);
} else {
- const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
+ const DWARFDataExtractor &debug_loc_data = DebugLocData();
const dw_offset_t debug_loc_offset = form_value.Unsigned();
size_t loc_list_length = DWARFExpression::LocationListSize(
@@ -3319,22 +3375,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
case DW_AT_start_scope: {
if (form_value.Form() == DW_FORM_sec_offset) {
DWARFRangeList dwarf_scope_ranges;
- const DWARFDebugRanges *debug_ranges = DebugRanges();
- debug_ranges->FindRanges(die.GetCU()->GetRangesBase(),
+ const DWARFDebugRangesBase *debug_ranges = DebugRanges();
+ debug_ranges->FindRanges(die.GetCU(),
form_value.Unsigned(),
dwarf_scope_ranges);
-
- // All DW_AT_start_scope are relative to the base address of the
- // compile unit. We add the compile unit base address to make
- // sure all the addresses are properly fixed up.
- for (size_t i = 0, count = dwarf_scope_ranges.GetSize();
- i < count; ++i) {
- const DWARFRangeList::Entry &range =
- dwarf_scope_ranges.GetEntryRef(i);
- scope_ranges.Append(range.GetRangeBase() +
- die.GetCU()->GetBaseAddress(),
- range.GetByteSize());
- }
} else {
// TODO: Handle the case when DW_AT_start_scope have form
// constant. The
@@ -3436,6 +3480,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
is_static_lifetime = true;
}
SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ // Set the module of the expression to the linked module
+ // instead of the oject file so the relocated address can be
+ // found there.
+ location.SetModule(debug_map_symfile->GetObjectFile()->GetModule());
if (is_static_lifetime) {
if (is_external)
@@ -3736,6 +3785,60 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc,
return vars_added;
}
+/// Collect call graph edges present in a function DIE.
+static std::vector<lldb_private::CallEdge>
+CollectCallEdges(DWARFDIE function_die) {
+ // Check if the function has a supported call site-related attribute.
+ // TODO: In the future it may be worthwhile to support call_all_source_calls.
+ uint64_t has_call_edges =
+ function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0);
+ if (!has_call_edges)
+ return {};
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+ LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}",
+ function_die.GetPubname());
+
+ // Scan the DIE for TAG_call_site entries.
+ // TODO: A recursive scan of all blocks in the subprogram is needed in order
+ // to be DWARF5-compliant. This may need to be done lazily to be performant.
+ // For now, assume that all entries are nested directly under the subprogram
+ // (this is the kind of DWARF LLVM produces) and parse them eagerly.
+ std::vector<CallEdge> call_edges;
+ for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid();
+ child = child.GetSibling()) {
+ if (child.Tag() != DW_TAG_call_site)
+ continue;
+
+ // Extract DW_AT_call_origin (the call target's DIE).
+ DWARFDIE call_origin = child.GetReferencedDIE(DW_AT_call_origin);
+ if (!call_origin.IsValid()) {
+ LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
+ function_die.GetPubname());
+ continue;
+ }
+
+ // Extract DW_AT_call_return_pc (the PC the call returns to) if it's
+ // available. It should only ever be unavailable for tail call edges, in
+ // which case use LLDB_INVALID_ADDRESS.
+ addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc,
+ LLDB_INVALID_ADDRESS);
+
+ LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
+ call_origin.GetPubname(), return_pc);
+ call_edges.emplace_back(call_origin.GetMangledName(), return_pc);
+ }
+ return call_edges;
+}
+
+std::vector<lldb_private::CallEdge>
+SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) {
+ DWARFDIE func_die = GetDIEFromUID(func_id.GetID());
+ if (func_die.IsValid())
+ return CollectCallEdges(func_die);
+ return {};
+}
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -3745,6 +3848,14 @@ uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; }
void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); }
+void SymbolFileDWARF::DumpClangAST(Stream &s) {
+ TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+ ClangASTContext *clang = llvm::dyn_cast_or_null<ClangASTContext>(ts);
+ if (!clang)
+ return;
+ clang->Dump(s);
+}
+
SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) {
lldb::ModuleSP module_sp(m_debug_map_module_wp.lock());
@@ -3760,6 +3871,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() {
DWARFExpression::LocationListFormat
SymbolFileDWARF::GetLocationListFormat() const {
+ if (m_data_debug_loclists.m_data.GetByteSize() > 0)
+ return DWARFExpression::LocLists;
return DWARFExpression::RegularLocationList;
}
@@ -3768,9 +3881,9 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() {
ModuleSpec module_spec;
module_spec.GetFileSpec() = m_obj_file->GetFileSpec();
module_spec.GetSymbolFileSpec() =
- FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false);
+ FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp");
FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec);
- if (dwp_filespec.Exists()) {
+ if (FileSystem::Instance().Exists(dwp_filespec)) {
m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(),
dwp_filespec);
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index a5f2ac8f3e7d..d351289f8b51 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -10,8 +10,6 @@
#ifndef SymbolFileDWARF_SymbolFileDWARF_h_
#define SymbolFileDWARF_SymbolFileDWARF_h_
-// C Includes
-// C++ Includes
#include <list>
#include <map>
#include <mutex>
@@ -19,7 +17,6 @@
#include <unordered_map>
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Threading.h"
@@ -35,7 +32,6 @@
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
-// Project includes
#include "DWARFDataExtractor.h"
#include "DWARFDefines.h"
#include "DWARFIndex.h"
@@ -53,7 +49,7 @@ class DWARFDebugAranges;
class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
-class DWARFDebugRanges;
+class DWARFDebugRangesBase;
class DWARFDeclContext;
class DWARFDIECollection;
class DWARFFormValue;
@@ -73,9 +69,6 @@ public:
friend class DWARFUnit;
friend class DWARFDIE;
friend class DWARFASTParserClang;
- friend class DWARFASTParserGo;
- friend class DWARFASTParserJava;
- friend class DWARFASTParserOCaml;
//------------------------------------------------------------------
// Static Functions
@@ -114,36 +107,34 @@ public:
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+ bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
- bool ParseCompileUnitSupportFiles(
- const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) override;
+ bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+ lldb_private::FileSpecList &support_files) override;
- bool
- ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+ bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
+
+ size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
-
- size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseBlocksRecursive(lldb_private::Function &func) override;
size_t
ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override;
bool CompleteType(lldb_private::CompilerType &compiler_type) override;
@@ -168,12 +159,13 @@ public:
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
- uint32_t resolve_scope,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
uint32_t
ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines, uint32_t resolve_scope,
+ bool check_inlines,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
@@ -189,8 +181,8 @@ public:
uint32_t
FindFunctions(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ lldb::FunctionNameType name_type_mask, bool include_inlines,
+ bool append, lldb_private::SymbolContextList &sc_list) override;
uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
bool include_inlines, bool append,
@@ -201,8 +193,7 @@ public:
std::vector<lldb_private::ConstString> &mangled_names) override;
uint32_t
- FindTypes(const lldb_private::SymbolContext &sc,
- const lldb_private::ConstString &name,
+ FindTypes(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
@@ -214,19 +205,20 @@ public:
lldb_private::TypeList *GetTypeList() override;
size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
void PreloadSymbols() override;
+ std::recursive_mutex &GetModuleMutex() const override;
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -234,17 +226,20 @@ public:
uint32_t GetPluginVersion() override;
- const lldb_private::DWARFDataExtractor &get_debug_abbrev_data();
- const lldb_private::DWARFDataExtractor &get_debug_addr_data();
+ virtual const lldb_private::DWARFDataExtractor &get_debug_abbrev_data();
+ virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data();
const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
const lldb_private::DWARFDataExtractor &get_debug_frame_data();
- const lldb_private::DWARFDataExtractor &get_debug_info_data();
+ virtual const lldb_private::DWARFDataExtractor &get_debug_info_data();
const lldb_private::DWARFDataExtractor &get_debug_line_data();
+ const lldb_private::DWARFDataExtractor &get_debug_line_str_data();
const lldb_private::DWARFDataExtractor &get_debug_macro_data();
const lldb_private::DWARFDataExtractor &get_debug_loc_data();
+ const lldb_private::DWARFDataExtractor &get_debug_loclists_data();
const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
- const lldb_private::DWARFDataExtractor &get_debug_str_data();
- const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
+ const lldb_private::DWARFDataExtractor &get_debug_rnglists_data();
+ virtual const lldb_private::DWARFDataExtractor &get_debug_str_data();
+ virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
const lldb_private::DWARFDataExtractor &get_debug_types_data();
const lldb_private::DWARFDataExtractor &get_apple_names_data();
const lldb_private::DWARFDataExtractor &get_apple_types_data();
@@ -260,9 +255,11 @@ public:
const DWARFDebugInfo *DebugInfo() const;
- DWARFDebugRanges *DebugRanges();
+ DWARFDebugRangesBase *DebugRanges();
- const DWARFDebugRanges *DebugRanges() const;
+ const DWARFDebugRangesBase *DebugRanges() const;
+
+ const lldb_private::DWARFDataExtractor &DebugLocData();
static bool SupportedVersion(uint16_t version);
@@ -316,8 +313,13 @@ public:
DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
const DWARFDIE &die);
+ std::vector<lldb_private::CallEdge>
+ ParseCallEdgesInFunction(UserID func_id) override;
+
void Dump(lldb_private::Stream &s) override;
+ void DumpClangAST(lldb_private::Stream &s) override;
+
protected:
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
DIEToTypePtr;
@@ -352,14 +354,13 @@ protected:
bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc);
- lldb_private::Function *
- ParseCompileUnitFunction(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die);
+ lldb_private::Function *ParseFunction(lldb_private::CompileUnit &comp_unit,
+ const DWARFDIE &die);
- size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc,
- lldb_private::Block *parent_block,
- const DWARFDIE &die,
- lldb::addr_t subprogram_low_pc, uint32_t depth);
+ size_t ParseBlocksRecursive(lldb_private::CompileUnit &comp_unit,
+ lldb_private::Block *parent_block,
+ const DWARFDIE &die,
+ lldb::addr_t subprogram_low_pc, uint32_t depth);
size_t ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
bool parse_siblings, bool parse_children);
@@ -466,9 +467,12 @@ protected:
DWARFDataSegment m_data_debug_frame;
DWARFDataSegment m_data_debug_info;
DWARFDataSegment m_data_debug_line;
+ DWARFDataSegment m_data_debug_line_str;
DWARFDataSegment m_data_debug_macro;
DWARFDataSegment m_data_debug_loc;
+ DWARFDataSegment m_data_debug_loclists;
DWARFDataSegment m_data_debug_ranges;
+ DWARFDataSegment m_data_debug_rnglists;
DWARFDataSegment m_data_debug_str;
DWARFDataSegment m_data_debug_str_offsets;
DWARFDataSegment m_data_debug_types;
@@ -498,7 +502,7 @@ protected:
typedef std::shared_ptr<std::set<DIERef>> DIERefSetSP;
typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
- std::unique_ptr<DWARFDebugRanges> m_ranges;
+ std::unique_ptr<DWARFDebugRangesBase> m_ranges;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 39c70d146524..2c1e6416a935 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -7,10 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "SymbolFileDWARFDebugMap.h"
#include "DWARFDebugAranges.h"
@@ -90,11 +86,10 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
for (uint32_t idx = comp_unit_info->first_symbol_index +
2; // Skip the N_SO and N_OSO
- idx < oso_end_idx;
- ++idx) {
+ idx < oso_end_idx; ++idx) {
Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
if (exe_symbol) {
- if (exe_symbol->IsDebug() == false)
+ if (!exe_symbol->IsDebug())
continue;
switch (exe_symbol->GetType()) {
@@ -184,7 +179,7 @@ public:
GetSymbolVendor(bool can_create = true,
lldb_private::Stream *feedback_strm = NULL) override {
// Scope for locker
- if (m_symfile_ap.get() || can_create == false)
+ if (m_symfile_ap.get() || !can_create)
return m_symfile_ap.get();
ModuleSP exe_module_sp(m_exe_module_wp.lock());
@@ -351,7 +346,7 @@ void SymbolFileDWARFDebugMap::InitOSO() {
so_symbol->GetType() == eSymbolTypeSourceFile &&
oso_symbol->GetType() == eSymbolTypeObjectFile) {
m_compile_unit_infos[i].so_file.SetFile(
- so_symbol->GetName().AsCString(), false, FileSpec::Style::native);
+ so_symbol->GetName().AsCString(), FileSpec::Style::native);
m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
m_compile_unit_infos[i].oso_mod_time =
llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
@@ -421,10 +416,13 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
comp_unit_info->oso_sp;
const char *oso_path = comp_unit_info->oso_path.GetCString();
- FileSpec oso_file(oso_path, false);
+ FileSpec oso_file(oso_path);
ConstString oso_object;
- if (oso_file.Exists()) {
- auto oso_mod_time = FileSystem::GetModificationTime(oso_file);
+ if (FileSystem::Instance().Exists(oso_file)) {
+ // The modification time returned by the FS can have a higher precision
+ // than the one from the CU.
+ auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
+ FileSystem::Instance().GetModificationTime(oso_file));
if (oso_mod_time != comp_unit_info->oso_mod_time) {
obj_file->GetModule()->ReportError(
"debug map object file '%s' has changed (actual time is "
@@ -490,7 +488,12 @@ ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
- CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc);
+ return GetSymbolFile(*sc.comp_unit);
+}
+
+SymbolFileDWARF *
+SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
+ CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
if (comp_unit_info)
return GetSymbolFileByCompUnitInfo(comp_unit_info);
return NULL;
@@ -518,7 +521,8 @@ uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
- if (oso_idx < m_compile_unit_infos.size())
+ unsigned size = m_compile_unit_infos.size();
+ if (oso_idx < size)
return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
return NULL;
}
@@ -597,9 +601,14 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
+ return GetCompUnitInfo(*sc.comp_unit);
+}
+
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i = 0; i < cu_count; ++i) {
- if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
+ if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
return &m_compile_unit_infos[i];
}
return NULL;
@@ -617,50 +626,46 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
}
lldb::LanguageType
-SymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLanguage(sc);
+ return oso_dwarf->ParseLanguage(comp_unit);
return eLanguageTypeUnknown;
}
-size_t
-SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitFunctions(sc);
+ return oso_dwarf->ParseFunctions(comp_unit);
return 0;
}
-bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable(
- const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitLineTable(sc);
+ return oso_dwarf->ParseLineTable(comp_unit);
return false;
}
-bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros(
- const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitDebugMacros(sc);
+ return oso_dwarf->ParseDebugMacros(comp_unit);
return false;
}
-bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles(
- const SymbolContext &sc, FileSpecList &support_files) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files);
+ return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
return false;
}
-bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(
- const lldb_private::SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseCompileUnitIsOptimized(sc);
+ return oso_dwarf->ParseIsOptimized(comp_unit);
return false;
}
@@ -672,17 +677,21 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules(
return false;
}
-size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
+ CompileUnit *comp_unit = func.GetCompileUnit();
+ if (!comp_unit)
+ return 0;
+
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseFunctionBlocks(sc);
+ return oso_dwarf->ParseBlocksRecursive(func);
return 0;
}
-size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) {
- SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
+size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
+ SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
if (oso_dwarf)
- return oso_dwarf->ParseTypes(sc);
+ return oso_dwarf->ParseTypes(comp_unit);
return 0;
}
@@ -702,6 +711,16 @@ Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
return NULL;
}
+llvm::Optional<SymbolFile::ArrayInfo>
+SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+ const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
+ return llvm::None;
+}
+
bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
bool success = false;
if (compiler_type) {
@@ -717,8 +736,10 @@ bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
return success;
}
-uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
- const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) {
+uint32_t
+SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
+ SymbolContextItem resolve_scope,
+ SymbolContext &sc) {
uint32_t resolved_flags = 0;
Symtab *symtab = m_obj_file->GetSymtab();
if (symtab) {
@@ -760,7 +781,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
- uint32_t resolve_scope, SymbolContextList &sc_list) {
+ SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
const uint32_t initial = sc_list.GetSize();
const uint32_t cu_count = GetNumCompileUnits();
@@ -792,8 +813,7 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
const std::vector<uint32_t>
&indexes, // Indexes into the symbol table that match "name"
- uint32_t max_matches,
- VariableList &variables) {
+ uint32_t max_matches, VariableList &variables) {
const uint32_t original_size = variables.GetSize();
const size_t match_count = indexes.size();
for (size_t i = 0; i < match_count; ++i) {
@@ -977,7 +997,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
uint32_t SymbolFileDWARFDebugMap::FindFunctions(
const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines, bool append,
SymbolContextList &sc_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
@@ -1032,7 +1052,7 @@ uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
}
size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ lldb::TypeClass type_mask,
TypeList &type_list) {
static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
Timer scoped_timer(func_cat,
@@ -1060,6 +1080,15 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
return type_list.GetSize() - initial_size;
}
+std::vector<lldb_private::CallEdge>
+SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) {
+ uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
+ SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
+ if (oso_dwarf)
+ return oso_dwarf->ParseCallEdgesInFunction(func_id);
+ return {};
+}
+
TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
const DWARFDeclContext &die_decl_ctx) {
TypeSP type_sp;
@@ -1136,7 +1165,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
// Only search all .o files for the definition if we don't need the
// implementation because otherwise, with a valid debug map we should have
// the ObjC class symbol and the code above should have found it.
- if (must_be_implementation == false) {
+ if (!must_be_implementation) {
TypeSP type_sp;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
@@ -1151,32 +1180,20 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
}
uint32_t SymbolFileDWARFDebugMap::FindTypes(
- const SymbolContext &sc, const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx, bool append,
- uint32_t max_matches,
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
TypeMap &types) {
if (!append)
types.Clear();
const uint32_t initial_types_size = types.GetSize();
- SymbolFileDWARF *oso_dwarf;
- if (sc.comp_unit) {
- oso_dwarf = GetSymbolFile(sc);
- if (oso_dwarf)
- return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append,
- max_matches, searched_symbol_files, types);
- } else {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches,
- searched_symbol_files, types);
- if (types.GetSize() >= max_matches)
- return true;
- else
- return false;
- });
- }
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types);
+ return types.GetSize() >= max_matches;
+ });
return types.GetSize() - initial_types_size;
}
@@ -1195,27 +1212,26 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes(
//}
CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const CompilerDeclContext *parent_decl_ctx) {
CompilerDeclContext matching_namespace;
- SymbolFileDWARF *oso_dwarf;
- if (sc.comp_unit) {
- oso_dwarf = GetSymbolFile(sc);
- if (oso_dwarf)
- matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx);
- } else {
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx);
+ ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
+ matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx);
- return (bool)matching_namespace;
- });
- }
+ return (bool)matching_namespace;
+ });
return matching_namespace;
}
+void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
+ ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
+ oso_dwarf->DumpClangAST(s);
+ return true;
+ });
+}
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 550f74a203ea..176eadeeca71 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -56,27 +56,33 @@ public:
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
- bool ParseCompileUnitSupportFiles(
- const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) override;
- bool
- ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override;
+ ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
+
+ size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+ lldb_private::FileSpecList &support_files) override;
+
+ bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
+
+ size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
+
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
- size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseBlocksRecursive(lldb_private::Function &func) override;
size_t
ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override;
+
lldb_private::CompilerDeclContext
GetDeclContextForUID(lldb::user_id_t uid) override;
lldb_private::CompilerDeclContext
@@ -86,11 +92,12 @@ public:
bool CompleteType(lldb_private::CompilerType &compiler_type) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
- uint32_t resolve_scope,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
uint32_t
ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines, uint32_t resolve_scope,
+ bool check_inlines,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
FindGlobalVariables(const lldb_private::ConstString &name,
@@ -103,25 +110,27 @@ public:
uint32_t
FindFunctions(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ lldb::FunctionNameType name_type_mask, bool include_inlines,
+ bool append, lldb_private::SymbolContextList &sc_list) override;
uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
- FindTypes(const lldb_private::SymbolContext &sc,
- const lldb_private::ConstString &name,
+ FindTypes(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
lldb_private::TypeMap &types) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
+ std::vector<lldb_private::CallEdge>
+ ParseCallEdgesInFunction(lldb_private::UserID func_id) override;
+
+ void DumpClangAST(lldb_private::Stream &s) override;
//------------------------------------------------------------------
// PluginInterface protocol
@@ -189,6 +198,7 @@ protected:
bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec);
CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc);
+ CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit);
size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module,
std::vector<CompileUnitInfo *> &cu_infos);
@@ -206,6 +216,7 @@ protected:
uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info);
SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc);
+ SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit);
SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 15fe362fa117..7881448535b8 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -61,14 +61,6 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu,
}
DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() {
- // A clang module is found via a skeleton CU, but is not a proper DWO.
- // Clang modules have a .debug_info section instead of the *_dwo variant.
- if (auto *section_list = m_obj_file->GetSectionList(false))
- 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);
@@ -126,6 +118,37 @@ DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
return m_base_dwarf_cu;
}
+const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_abbrev_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugAbbrevDwo,
+ m_data_debug_abbrev);
+}
+
+const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_addr_data() {
+ // For single file split dwarf case (when we have .dwo sections in a .o),
+ // we do not want to use the .debug_addr section from .o file,
+ // but want to get one from the final executable.
+ // For regular split debug case, .dwo file does not contain the
+ // .debug_addr, so we would always fall back to such lookup anyways.
+ llvm::call_once(m_data_debug_addr.m_flag, [this] {
+ SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr,
+ std::ref(m_data_debug_addr.m_data));
+ });
+ return m_data_debug_addr.m_data;
+}
+
+const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info);
+}
+
+const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStrDwo, m_data_debug_str);
+}
+
+const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_offsets_data() {
+ return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsetsDwo,
+ m_data_debug_str_offsets);
+}
+
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 483a19512a36..b9ed37547aca 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -10,10 +10,6 @@
#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "SymbolFileDWARF.h"
class SymbolFileDWARFDwo : public SymbolFileDWARF {
@@ -50,6 +46,12 @@ public:
DWARFUnit *GetBaseCompileUnit() override;
+ const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override;
+ const lldb_private::DWARFDataExtractor &get_debug_addr_data() override;
+ const lldb_private::DWARFDataExtractor &get_debug_info_data() override;
+ const lldb_private::DWARFDataExtractor &get_debug_str_data() override;
+ const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override;
+
protected:
void LoadSectionData(lldb::SectionType sect_type,
lldb_private::DWARFDataExtractor &data) override;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
index b1b505b5899f..905ba0a5c7b8 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -10,10 +10,6 @@
#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"
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
index ae10e7179e33..73226dfc130f 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -9,10 +9,6 @@
#include "SymbolFileDWARFDwp.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -30,7 +26,7 @@ lldbSectTypeToLlvmSectionKind(lldb::SectionType type) {
case lldb::eSectionTypeDWARFDebugLine:
return llvm::DW_SECT_LINE;
case lldb::eSectionTypeDWARFDebugLoc:
- return llvm::DW_SECT_LOC;
+ return llvm::DW_SECT_LOC;
case lldb::eSectionTypeDWARFDebugStrOffsets:
return llvm::DW_SECT_STR_OFFSETS;
// case lldb::eSectionTypeDWARFDebugMacinfo:
@@ -50,7 +46,8 @@ SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp,
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,
+ module_sp, &file_spec, file_offset,
+ lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp,
file_data_offset);
if (obj_file == nullptr)
return nullptr;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
index 470d1c5b1c48..87f4d9402335 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -10,14 +10,10 @@
#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"
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 8273d975e57d..dd912aecf0d8 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -9,10 +9,6 @@
#include "UniqueDWARFASTType.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/Declaration.h"
bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
diff --git a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index 5d51044cbe1a..1e6b164e9457 100644
--- a/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -10,14 +10,10 @@
#ifndef lldb_UniqueDWARFASTType_h_
#define lldb_UniqueDWARFASTType_h_
-// C Includes
-// C++ Includes
#include <vector>
-// Other libraries and framework includes
#include "llvm/ADT/DenseMap.h"
-// Project includes
#include "DWARFDIE.h"
#include "lldb/Symbol/Declaration.h"
diff --git a/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt
new file mode 100644
index 000000000000..da2d7fe8108a
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt
@@ -0,0 +1,21 @@
+add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN
+ CompileUnitIndex.cpp
+ DWARFLocationExpression.cpp
+ PdbAstBuilder.cpp
+ PdbIndex.cpp
+ PdbSymUid.cpp
+ PdbUtil.cpp
+ SymbolFileNativePDB.cpp
+ UdtRecordCompleter.cpp
+
+ LINK_LIBS
+ clangAST
+ clangLex
+ lldbCore
+ lldbSymbol
+ lldbUtility
+ LINK_COMPONENTS
+ DebugInfoCodeView
+ DebugInfoPDB
+ Support
+ )
diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
new file mode 100644
index 000000000000..67ea05767fde
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp
@@ -0,0 +1,217 @@
+//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CompileUnitIndex.h"
+
+#include "PdbIndex.h"
+#include "PdbUtil.h"
+
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Support/Path.h"
+
+#include "lldb/Utility/LLDBAssert.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) {
+ if (main == other)
+ return true;
+
+ // If the files refer to the local file system, we can just ask the file
+ // system if they're equivalent. But if the source isn't present on disk
+ // then we still want to try.
+ if (llvm::sys::fs::equivalent(main, other))
+ return true;
+
+ llvm::SmallString<64> normalized(other);
+ llvm::sys::path::native(normalized);
+ return main.equals_lower(normalized);
+}
+
+static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) {
+ cci.m_compile_opts.emplace();
+ llvm::cantFail(
+ SymbolDeserializer::deserializeAs<Compile3Sym>(sym, *cci.m_compile_opts));
+}
+
+static void ParseObjname(const CVSymbol &sym, CompilandIndexItem &cci) {
+ cci.m_obj_name.emplace();
+ llvm::cantFail(
+ SymbolDeserializer::deserializeAs<ObjNameSym>(sym, *cci.m_obj_name));
+}
+
+static void ParseBuildInfo(PdbIndex &index, const CVSymbol &sym,
+ CompilandIndexItem &cci) {
+ BuildInfoSym bis(SymbolRecordKind::BuildInfoSym);
+ llvm::cantFail(SymbolDeserializer::deserializeAs<BuildInfoSym>(sym, bis));
+
+ // S_BUILDINFO just points to an LF_BUILDINFO in the IPI stream. Let's do
+ // a little extra work to pull out the LF_BUILDINFO.
+ LazyRandomTypeCollection &types = index.ipi().typeCollection();
+ llvm::Optional<CVType> cvt = types.tryGetType(bis.BuildId);
+
+ if (!cvt || cvt->kind() != LF_BUILDINFO)
+ return;
+
+ BuildInfoRecord bir;
+ llvm::cantFail(TypeDeserializer::deserializeAs<BuildInfoRecord>(*cvt, bir));
+ cci.m_build_info.assign(bir.ArgIndices.begin(), bir.ArgIndices.end());
+}
+
+static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) {
+ const CVSymbolArray &syms = item.m_debug_stream.getSymbolArray();
+
+ // This is a private function, it shouldn't be called if the information
+ // has already been parsed.
+ lldbassert(!item.m_obj_name);
+ lldbassert(!item.m_compile_opts);
+ lldbassert(item.m_build_info.empty());
+
+ // We're looking for 3 things. S_COMPILE3, S_OBJNAME, and S_BUILDINFO.
+ int found = 0;
+ for (const CVSymbol &sym : syms) {
+ switch (sym.kind()) {
+ case S_COMPILE3:
+ ParseCompile3(sym, item);
+ break;
+ case S_OBJNAME:
+ ParseObjname(sym, item);
+ break;
+ case S_BUILDINFO:
+ ParseBuildInfo(index, sym, item);
+ break;
+ default:
+ continue;
+ }
+ if (++found >= 3)
+ break;
+ }
+}
+
+CompilandIndexItem::CompilandIndexItem(
+ PdbCompilandId id, llvm::pdb::ModuleDebugStreamRef debug_stream,
+ llvm::pdb::DbiModuleDescriptor descriptor)
+ : m_id(id), m_debug_stream(std::move(debug_stream)),
+ m_module_descriptor(std::move(descriptor)) {}
+
+CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) {
+ auto result = m_comp_units.try_emplace(modi, nullptr);
+ if (!result.second)
+ return *result.first->second;
+
+ // Find the module list and load its debug information stream and cache it
+ // since we need to use it for almost all interesting operations.
+ const DbiModuleList &modules = m_index.dbi().modules();
+ llvm::pdb::DbiModuleDescriptor descriptor = modules.getModuleDescriptor(modi);
+ uint16_t stream = descriptor.getModuleStreamIndex();
+ std::unique_ptr<llvm::msf::MappedBlockStream> stream_data =
+ m_index.pdb().createIndexedStream(stream);
+ llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor,
+ std::move(stream_data));
+ cantFail(debug_stream.reload());
+
+ std::unique_ptr<CompilandIndexItem> &cci = result.first->second;
+
+ cci = llvm::make_unique<CompilandIndexItem>(
+ PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor));
+ ParseExtendedInfo(m_index, *cci);
+
+ cci->m_strings.initialize(debug_stream.getSubsectionsArray());
+ PDBStringTable &strings = cantFail(m_index.pdb().getStringTable());
+ cci->m_strings.setStrings(strings.getStringTable());
+
+ // We want the main source file to always comes first. Note that we can't
+ // just push_back the main file onto the front because `GetMainSourceFile`
+ // computes it in such a way that it doesn't own the resulting memory. So we
+ // have to iterate the module file list comparing each one to the main file
+ // name until we find it, and we can cache that one since the memory is backed
+ // by a contiguous chunk inside the mapped PDB.
+ llvm::SmallString<64> main_file = GetMainSourceFile(*cci);
+ std::string s = main_file.str();
+ llvm::sys::path::native(main_file);
+
+ uint32_t file_count = modules.getSourceFileCount(modi);
+ cci->m_file_list.reserve(file_count);
+ bool found_main_file = false;
+ for (llvm::StringRef file : modules.source_files(modi)) {
+ if (!found_main_file && IsMainFile(main_file, file)) {
+ cci->m_file_list.insert(cci->m_file_list.begin(), file);
+ found_main_file = true;
+ continue;
+ }
+ cci->m_file_list.push_back(file);
+ }
+
+ return *cci;
+}
+
+const CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) const {
+ auto iter = m_comp_units.find(modi);
+ if (iter == m_comp_units.end())
+ return nullptr;
+ return iter->second.get();
+}
+
+CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) {
+ auto iter = m_comp_units.find(modi);
+ if (iter == m_comp_units.end())
+ return nullptr;
+ return iter->second.get();
+}
+
+llvm::SmallString<64>
+CompileUnitIndex::GetMainSourceFile(const CompilandIndexItem &item) const {
+ // LF_BUILDINFO contains a list of arg indices which point to LF_STRING_ID
+ // records in the IPI stream. The order of the arg indices is as follows:
+ // [0] - working directory where compiler was invoked.
+ // [1] - absolute path to compiler binary
+ // [2] - source file name
+ // [3] - path to compiler generated PDB (the /Zi PDB, although this entry gets
+ // added even when using /Z7)
+ // [4] - full command line invocation.
+ //
+ // We need to form the path [0]\[2] to generate the full path to the main
+ // file.source
+ if (item.m_build_info.size() < 3)
+ return {""};
+
+ LazyRandomTypeCollection &types = m_index.ipi().typeCollection();
+
+ StringIdRecord working_dir;
+ StringIdRecord file_name;
+ CVType dir_cvt = types.getType(item.m_build_info[0]);
+ CVType file_cvt = types.getType(item.m_build_info[2]);
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<StringIdRecord>(dir_cvt, working_dir));
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<StringIdRecord>(file_cvt, file_name));
+
+ llvm::sys::path::Style style = working_dir.String.startswith("/")
+ ? llvm::sys::path::Style::posix
+ : llvm::sys::path::Style::windows;
+ if (llvm::sys::path::is_absolute(file_name.String, style))
+ return file_name.String;
+
+ llvm::SmallString<64> absolute_path = working_dir.String;
+ llvm::sys::path::append(absolute_path, file_name.String);
+ return absolute_path;
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
new file mode 100644
index 000000000000..c965870da44b
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h
@@ -0,0 +1,95 @@
+//===-- CompileUnitIndex.h --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H
+#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include "PdbSymUid.h"
+
+#include <map>
+#include <memory>
+
+namespace lldb_private {
+
+namespace npdb {
+class PdbIndex;
+
+/// Represents a single compile unit. This class is useful for collecting the
+/// important accessors and information about a compile unit from disparate
+/// parts of the PDB into a single place, simplifying acess to compile unit
+/// information for the callers.
+struct CompilandIndexItem {
+ CompilandIndexItem(PdbCompilandId m_id,
+ llvm::pdb::ModuleDebugStreamRef debug_stream,
+ llvm::pdb::DbiModuleDescriptor descriptor);
+
+ // index of this compile unit.
+ PdbCompilandId m_id;
+
+ // debug stream.
+ llvm::pdb::ModuleDebugStreamRef m_debug_stream;
+
+ // dbi module descriptor.
+ llvm::pdb::DbiModuleDescriptor m_module_descriptor;
+
+ llvm::codeview::StringsAndChecksumsRef m_strings;
+
+ // List of files which contribute to this compiland.
+ std::vector<llvm::StringRef> m_file_list;
+
+ // Maps virtual address to global symbol id, which can then be used to
+ // locate the exact compile unit and offset of the symbol. Note that this
+ // is intentionally an ordered map so that we can find all symbols up to a
+ // given starting address.
+ std::map<lldb::addr_t, PdbSymUid> m_symbols_by_va;
+
+ // S_COMPILE3 sym describing compilation settings for the module.
+ llvm::Optional<llvm::codeview::Compile3Sym> m_compile_opts;
+
+ // S_OBJNAME sym describing object name.
+ llvm::Optional<llvm::codeview::ObjNameSym> m_obj_name;
+
+ // LF_BUILDINFO sym describing source file name, working directory,
+ // command line, etc. This usually contains exactly 5 items which
+ // are references to other strings.
+ llvm::SmallVector<llvm::codeview::TypeIndex, 5> m_build_info;
+};
+
+/// Indexes information about all compile units. This is really just a map of
+/// global compile unit index to |CompilandIndexItem| structures.
+class CompileUnitIndex {
+ PdbIndex &m_index;
+ llvm::DenseMap<uint16_t, std::unique_ptr<CompilandIndexItem>> m_comp_units;
+
+public:
+ explicit CompileUnitIndex(PdbIndex &index) : m_index(index) {}
+
+ CompilandIndexItem &GetOrCreateCompiland(uint16_t modi);
+
+ const CompilandIndexItem *GetCompiland(uint16_t modi) const;
+
+ CompilandIndexItem *GetCompiland(uint16_t modi);
+
+ llvm::SmallString<64> GetMainSourceFile(const CompilandIndexItem &item) const;
+};
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
new file mode 100644
index 000000000000..7b62530e4680
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -0,0 +1,673 @@
+//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFLocationExpression.h"
+
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/StreamBuffer.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Support/Endian.h"
+
+#include "PdbUtil.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+static const uint32_t g_code_view_to_lldb_registers_x86[] = {
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_i386, // AL
+ lldb_cl_i386, // CL
+ lldb_dl_i386, // DL
+ lldb_bl_i386, // BL
+ lldb_ah_i386, // AH
+ lldb_ch_i386, // CH
+ lldb_dh_i386, // DH
+ lldb_bh_i386, // BH
+ lldb_ax_i386, // AX
+ lldb_cx_i386, // CX
+ lldb_dx_i386, // DX
+ lldb_bx_i386, // BX
+ lldb_sp_i386, // SP
+ lldb_bp_i386, // BP
+ lldb_si_i386, // SI
+ lldb_di_i386, // DI
+ lldb_eax_i386, // EAX
+ lldb_ecx_i386, // ECX
+ lldb_edx_i386, // EDX
+ lldb_ebx_i386, // EBX
+ lldb_esp_i386, // ESP
+ lldb_ebp_i386, // EBP
+ lldb_esi_i386, // ESI
+ lldb_edi_i386, // EDI
+ lldb_es_i386, // ES
+ lldb_cs_i386, // CS
+ lldb_ss_i386, // SS
+ lldb_ds_i386, // DS
+ lldb_fs_i386, // FS
+ lldb_gs_i386, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ lldb_eip_i386, // EIP
+ lldb_eflags_i386, // EFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_i386, // DR0
+ lldb_dr1_i386, // DR1
+ lldb_dr2_i386, // DR2
+ lldb_dr3_i386, // DR3
+ lldb_dr4_i386, // DR4
+ lldb_dr5_i386, // DR5
+ lldb_dr6_i386, // DR6
+ lldb_dr7_i386, // DR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_i386, // ST0
+ lldb_st1_i386, // ST1
+ lldb_st2_i386, // ST2
+ lldb_st3_i386, // ST3
+ lldb_st4_i386, // ST4
+ lldb_st5_i386, // ST5
+ lldb_st6_i386, // ST6
+ lldb_st7_i386, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_i386, // MM0
+ lldb_mm1_i386, // MM1
+ lldb_mm2_i386, // MM2
+ lldb_mm3_i386, // MM3
+ lldb_mm4_i386, // MM4
+ lldb_mm5_i386, // MM5
+ lldb_mm6_i386, // MM6
+ lldb_mm7_i386, // MM7
+ lldb_xmm0_i386, // XMM0
+ lldb_xmm1_i386, // XMM1
+ lldb_xmm2_i386, // XMM2
+ lldb_xmm3_i386, // XMM3
+ lldb_xmm4_i386, // XMM4
+ lldb_xmm5_i386, // XMM5
+ lldb_xmm6_i386, // XMM6
+ lldb_xmm7_i386 // XMM7
+};
+
+static const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_x86_64, // AL
+ lldb_cl_x86_64, // CL
+ lldb_dl_x86_64, // DL
+ lldb_bl_x86_64, // BL
+ lldb_ah_x86_64, // AH
+ lldb_ch_x86_64, // CH
+ lldb_dh_x86_64, // DH
+ lldb_bh_x86_64, // BH
+ lldb_ax_x86_64, // AX
+ lldb_cx_x86_64, // CX
+ lldb_dx_x86_64, // DX
+ lldb_bx_x86_64, // BX
+ lldb_sp_x86_64, // SP
+ lldb_bp_x86_64, // BP
+ lldb_si_x86_64, // SI
+ lldb_di_x86_64, // DI
+ lldb_eax_x86_64, // EAX
+ lldb_ecx_x86_64, // ECX
+ lldb_edx_x86_64, // EDX
+ lldb_ebx_x86_64, // EBX
+ lldb_esp_x86_64, // ESP
+ lldb_ebp_x86_64, // EBP
+ lldb_esi_x86_64, // ESI
+ lldb_edi_x86_64, // EDI
+ lldb_es_x86_64, // ES
+ lldb_cs_x86_64, // CS
+ lldb_ss_x86_64, // SS
+ lldb_ds_x86_64, // DS
+ lldb_fs_x86_64, // FS
+ lldb_gs_x86_64, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ LLDB_INVALID_REGNUM, // EIP
+ LLDB_INVALID_REGNUM, // EFLAGS
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_dr0_x86_64, // DR0
+ lldb_dr1_x86_64, // DR1
+ lldb_dr2_x86_64, // DR2
+ lldb_dr3_x86_64, // DR3
+ lldb_dr4_x86_64, // DR4
+ lldb_dr5_x86_64, // DR5
+ lldb_dr6_x86_64, // DR6
+ lldb_dr7_x86_64, // DR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_x86_64, // ST0
+ lldb_st1_x86_64, // ST1
+ lldb_st2_x86_64, // ST2
+ lldb_st3_x86_64, // ST3
+ lldb_st4_x86_64, // ST4
+ lldb_st5_x86_64, // ST5
+ lldb_st6_x86_64, // ST6
+ lldb_st7_x86_64, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_x86_64, // MM0
+ lldb_mm1_x86_64, // MM1
+ lldb_mm2_x86_64, // MM2
+ lldb_mm3_x86_64, // MM3
+ lldb_mm4_x86_64, // MM4
+ lldb_mm5_x86_64, // MM5
+ lldb_mm6_x86_64, // MM6
+ lldb_mm7_x86_64, // MM7
+ lldb_xmm0_x86_64, // XMM0
+ lldb_xmm1_x86_64, // XMM1
+ lldb_xmm2_x86_64, // XMM2
+ lldb_xmm3_x86_64, // XMM3
+ lldb_xmm4_x86_64, // XMM4
+ lldb_xmm5_x86_64, // XMM5
+ lldb_xmm6_x86_64, // XMM6
+ lldb_xmm7_x86_64, // XMM7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_mxcsr_x86_64, // MXCSR
+ LLDB_INVALID_REGNUM, // EDXEAX
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // EMM0L
+ LLDB_INVALID_REGNUM, // EMM1L
+ LLDB_INVALID_REGNUM, // EMM2L
+ LLDB_INVALID_REGNUM, // EMM3L
+ LLDB_INVALID_REGNUM, // EMM4L
+ LLDB_INVALID_REGNUM, // EMM5L
+ LLDB_INVALID_REGNUM, // EMM6L
+ LLDB_INVALID_REGNUM, // EMM7L
+ LLDB_INVALID_REGNUM, // EMM0H
+ LLDB_INVALID_REGNUM, // EMM1H
+ LLDB_INVALID_REGNUM, // EMM2H
+ LLDB_INVALID_REGNUM, // EMM3H
+ LLDB_INVALID_REGNUM, // EMM4H
+ LLDB_INVALID_REGNUM, // EMM5H
+ LLDB_INVALID_REGNUM, // EMM6H
+ LLDB_INVALID_REGNUM, // EMM7H
+ LLDB_INVALID_REGNUM, // MM00
+ LLDB_INVALID_REGNUM, // MM01
+ LLDB_INVALID_REGNUM, // MM10
+ LLDB_INVALID_REGNUM, // MM11
+ LLDB_INVALID_REGNUM, // MM20
+ LLDB_INVALID_REGNUM, // MM21
+ LLDB_INVALID_REGNUM, // MM30
+ LLDB_INVALID_REGNUM, // MM31
+ LLDB_INVALID_REGNUM, // MM40
+ LLDB_INVALID_REGNUM, // MM41
+ LLDB_INVALID_REGNUM, // MM50
+ LLDB_INVALID_REGNUM, // MM51
+ LLDB_INVALID_REGNUM, // MM60
+ LLDB_INVALID_REGNUM, // MM61
+ LLDB_INVALID_REGNUM, // MM70
+ LLDB_INVALID_REGNUM, // MM71
+ lldb_xmm8_x86_64, // XMM8
+ lldb_xmm9_x86_64, // XMM9
+ lldb_xmm10_x86_64, // XMM10
+ lldb_xmm11_x86_64, // XMM11
+ lldb_xmm12_x86_64, // XMM12
+ lldb_xmm13_x86_64, // XMM13
+ lldb_xmm14_x86_64, // XMM14
+ lldb_xmm15_x86_64, // XMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM,
+ lldb_sil_x86_64, // SIL
+ lldb_dil_x86_64, // DIL
+ lldb_bpl_x86_64, // BPL
+ lldb_spl_x86_64, // SPL
+ lldb_rax_x86_64, // RAX
+ lldb_rbx_x86_64, // RBX
+ lldb_rcx_x86_64, // RCX
+ lldb_rdx_x86_64, // RDX
+ lldb_rsi_x86_64, // RSI
+ lldb_rdi_x86_64, // RDI
+ lldb_rbp_x86_64, // RBP
+ lldb_rsp_x86_64, // RSP
+ lldb_r8_x86_64, // R8
+ lldb_r9_x86_64, // R9
+ lldb_r10_x86_64, // R10
+ lldb_r11_x86_64, // R11
+ lldb_r12_x86_64, // R12
+ lldb_r13_x86_64, // R13
+ lldb_r14_x86_64, // R14
+ lldb_r15_x86_64, // R15
+ lldb_r8l_x86_64, // R8B
+ lldb_r9l_x86_64, // R9B
+ lldb_r10l_x86_64, // R10B
+ lldb_r11l_x86_64, // R11B
+ lldb_r12l_x86_64, // R12B
+ lldb_r13l_x86_64, // R13B
+ lldb_r14l_x86_64, // R14B
+ lldb_r15l_x86_64, // R15B
+ lldb_r8w_x86_64, // R8W
+ lldb_r9w_x86_64, // R9W
+ lldb_r10w_x86_64, // R10W
+ lldb_r11w_x86_64, // R11W
+ lldb_r12w_x86_64, // R12W
+ lldb_r13w_x86_64, // R13W
+ lldb_r14w_x86_64, // R14W
+ lldb_r15w_x86_64, // R15W
+ lldb_r8d_x86_64, // R8D
+ lldb_r9d_x86_64, // R9D
+ lldb_r10d_x86_64, // R10D
+ lldb_r11d_x86_64, // R11D
+ lldb_r12d_x86_64, // R12D
+ lldb_r13d_x86_64, // R13D
+ lldb_r14d_x86_64, // R14D
+ lldb_r15d_x86_64, // R15D
+ lldb_ymm0_x86_64, // AMD64_YMM0
+ lldb_ymm1_x86_64, // AMD64_YMM1
+ lldb_ymm2_x86_64, // AMD64_YMM2
+ lldb_ymm3_x86_64, // AMD64_YMM3
+ lldb_ymm4_x86_64, // AMD64_YMM4
+ lldb_ymm5_x86_64, // AMD64_YMM5
+ lldb_ymm6_x86_64, // AMD64_YMM6
+ lldb_ymm7_x86_64, // AMD64_YMM7
+ lldb_ymm8_x86_64, // AMD64_YMM8
+ lldb_ymm9_x86_64, // AMD64_YMM9
+ lldb_ymm10_x86_64, // AMD64_YMM10
+ lldb_ymm11_x86_64, // AMD64_YMM11
+ lldb_ymm12_x86_64, // AMD64_YMM12
+ lldb_ymm13_x86_64, // AMD64_YMM13
+ lldb_ymm14_x86_64, // AMD64_YMM14
+ lldb_ymm15_x86_64, // AMD64_YMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_bnd0_x86_64, // BND0
+ lldb_bnd1_x86_64, // BND1
+ lldb_bnd2_x86_64 // BND2
+};
+
+uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
+ llvm::codeview::RegisterId register_id) {
+ switch (arch_type) {
+ case llvm::Triple::x86:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86) /
+ sizeof(g_code_view_to_lldb_registers_x86[0]))
+ return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
+ register_id)];
+
+ switch (register_id) {
+ case llvm::codeview::RegisterId::MXCSR:
+ return lldb_mxcsr_i386;
+ case llvm::codeview::RegisterId::BND0:
+ return lldb_bnd0_i386;
+ case llvm::codeview::RegisterId::BND1:
+ return lldb_bnd1_i386;
+ case llvm::codeview::RegisterId::BND2:
+ return lldb_bnd2_i386;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ case llvm::Triple::x86_64:
+ if (static_cast<uint16_t>(register_id) <
+ sizeof(g_code_view_to_lldb_registers_x86_64) /
+ sizeof(g_code_view_to_lldb_registers_x86_64[0]))
+ return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
+ register_id)];
+
+ return LLDB_INVALID_REGNUM;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+}
+
+uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
+ if (register_id == llvm::codeview::RegisterId::VFRAME)
+ return LLDB_REGNUM_GENERIC_FP;
+
+ return LLDB_INVALID_REGNUM;
+}
+
+static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type,
+ llvm::codeview::RegisterId register_id,
+ RegisterKind &register_kind) {
+ register_kind = eRegisterKindLLDB;
+ uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id);
+ if (reg_num != LLDB_INVALID_REGNUM)
+ return reg_num;
+
+ register_kind = eRegisterKindGeneric;
+ return GetGenericRegisterNumber(register_id);
+}
+
+static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) {
+ switch (kind) {
+ case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ case SimpleTypeKind::Int32:
+ case SimpleTypeKind::Int32Long:
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ case SimpleTypeKind::Float128:
+ case SimpleTypeKind::Float80:
+ case SimpleTypeKind::Float64:
+ case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float16:
+ case SimpleTypeKind::NarrowCharacter:
+ case SimpleTypeKind::SignedCharacter:
+ case SimpleTypeKind::SByte:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti,
+ TpiStream &tpi) {
+ if (ti.isSimple()) {
+ SimpleTypeKind stk = ti.getSimpleKind();
+ return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)};
+ }
+
+ CVType cvt = tpi.getType(ti);
+ switch (cvt.kind()) {
+ case LF_MODIFIER: {
+ ModifierRecord mfr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
+ return GetIntegralTypeInfo(mfr.ModifiedType, tpi);
+ }
+ case LF_POINTER: {
+ PointerRecord pr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
+ return GetIntegralTypeInfo(pr.ReferentType, tpi);
+ }
+ case LF_ENUM: {
+ EnumRecord er;
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
+ return GetIntegralTypeInfo(er.UnderlyingType, tpi);
+ }
+ default:
+ assert(false && "Type is not integral!");
+ return {0, false};
+ }
+}
+
+template <typename StreamWriter>
+static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
+ StreamWriter &&writer) {
+ const ArchSpec &architecture = module->GetArchitecture();
+ ByteOrder byte_order = architecture.GetByteOrder();
+ uint32_t address_size = architecture.GetAddressByteSize();
+ uint32_t byte_size = architecture.GetDataByteSize();
+ if (byte_order == eByteOrderInvalid || address_size == 0)
+ return DWARFExpression(nullptr);
+
+ RegisterKind register_kind = eRegisterKindDWARF;
+ StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
+
+ if (!writer(stream, register_kind))
+ return DWARFExpression(nullptr);
+
+ DataBufferSP buffer =
+ std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
+ DataExtractor extractor(buffer, byte_order, address_size, byte_size);
+ DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
+ result.SetRegisterKind(register_kind);
+
+ return result;
+}
+
+static DWARFExpression MakeRegisterBasedLocationExpressionInternal(
+ llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset,
+ lldb::ModuleSP module) {
+ return MakeLocationExpressionInternal(
+ module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
+ uint32_t reg_num = GetRegisterNumber(
+ module->GetArchitecture().GetMachine(), reg, register_kind);
+ if (reg_num == LLDB_INVALID_REGNUM)
+ return false;
+
+ if (reg_num > 31) {
+ llvm::dwarf::LocationAtom base = relative_offset
+ ? llvm::dwarf::DW_OP_bregx
+ : llvm::dwarf::DW_OP_regx;
+ stream.PutHex8(base);
+ stream.PutULEB128(reg_num);
+ } else {
+ llvm::dwarf::LocationAtom base = relative_offset
+ ? llvm::dwarf::DW_OP_breg0
+ : llvm::dwarf::DW_OP_reg0;
+ stream.PutHex8(base + reg_num);
+ }
+
+ if (relative_offset)
+ stream.PutSLEB128(*relative_offset);
+
+ return true;
+ });
+}
+
+DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpression(
+ llvm::codeview::RegisterId reg, lldb::ModuleSP module) {
+ return MakeRegisterBasedLocationExpressionInternal(reg, llvm::None, module);
+}
+
+DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression(
+ llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module) {
+ return MakeRegisterBasedLocationExpressionInternal(reg, offset, module);
+}
+
+DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
+ uint16_t section, uint32_t offset, ModuleSP module) {
+ assert(section > 0);
+ assert(module);
+
+ return MakeLocationExpressionInternal(
+ module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
+ stream.PutHex8(llvm::dwarf::DW_OP_addr);
+
+ SectionList *section_list = module->GetSectionList();
+ assert(section_list);
+
+ // Section indices in PDB are 1-based, but in DWARF they are 0-based, so
+ // we need to subtract 1.
+ uint32_t section_idx = section - 1;
+ if (section_idx >= section_list->GetSize())
+ return false;
+
+ auto section_ptr = section_list->GetSectionAtIndex(section_idx);
+ if (!section_ptr)
+ return false;
+
+ stream.PutMaxHex64(section_ptr->GetFileAddress() + offset,
+ stream.GetAddressByteSize(), stream.GetByteOrder());
+
+ return true;
+ });
+}
+
+DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
+ TypeIndex underlying_ti, TpiStream &tpi, const llvm::APSInt &constant,
+ ModuleSP module) {
+ const ArchSpec &architecture = module->GetArchitecture();
+ uint32_t address_size = architecture.GetAddressByteSize();
+
+ size_t size = 0;
+ bool is_signed = false;
+ std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi);
+
+ union {
+ llvm::support::little64_t I;
+ llvm::support::ulittle64_t U;
+ } Value;
+
+ std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
+ buffer->SetByteSize(size);
+
+ llvm::ArrayRef<uint8_t> bytes;
+ if (is_signed) {
+ Value.I = constant.getSExtValue();
+ } else {
+ Value.U = constant.getZExtValue();
+ }
+
+ bytes = llvm::makeArrayRef(reinterpret_cast<const uint8_t *>(&Value), 8)
+ .take_front(size);
+ buffer->CopyData(bytes.data(), size);
+ DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
+ DWARFExpression result(nullptr, extractor, nullptr, 0, size);
+ return result;
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
new file mode 100644
index 000000000000..670e95ee8e3c
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
@@ -0,0 +1,42 @@
+//===-- DWARFLocationExpression.h -------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
+#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
+
+#include "lldb/lldb-forward.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+
+namespace llvm {
+class APSInt;
+namespace codeview {
+class TypeIndex;
+}
+namespace pdb {
+class TpiStream;
+}
+} // namespace llvm
+namespace lldb_private {
+namespace npdb {
+DWARFExpression
+MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg,
+ lldb::ModuleSP module);
+
+DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg,
+ int32_t offset,
+ lldb::ModuleSP module);
+DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
+ lldb::ModuleSP module);
+DWARFExpression MakeConstantLocationExpression(
+ llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi,
+ const llvm::APSInt &constant, lldb::ModuleSP module);
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
new file mode 100644
index 000000000000..8917fd092385
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -0,0 +1,1348 @@
+#include "PdbAstBuilder.h"
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Demangle/MicrosoftDemangle.h"
+
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "PdbUtil.h"
+#include "UdtRecordCompleter.h"
+
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index,
+ PdbCompilandSymId id) {
+ CVSymbol sym = index.ReadSymbolRecord(id);
+ if (symbolOpensScope(sym.kind())) {
+ // If this exact symbol opens a scope, we can just directly access its
+ // parent.
+ id.offset = getScopeParentOffset(sym);
+ // Global symbols have parent offset of 0. Return llvm::None to indicate
+ // this.
+ if (id.offset == 0)
+ return llvm::None;
+ return id;
+ }
+
+ // Otherwise we need to start at the beginning and iterate forward until we
+ // reach (or pass) this particular symbol
+ CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(id.modi);
+ const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
+
+ auto begin = syms.begin();
+ auto end = syms.at(id.offset);
+ std::vector<PdbCompilandSymId> scope_stack;
+
+ while (begin != end) {
+ if (id.offset == begin.offset()) {
+ // We have a match! Return the top of the stack
+ if (scope_stack.empty())
+ return llvm::None;
+ return scope_stack.back();
+ }
+ if (begin.offset() > id.offset) {
+ // We passed it. We couldn't even find this symbol record.
+ lldbassert(false && "Invalid compiland symbol id!");
+ return llvm::None;
+ }
+
+ // We haven't found the symbol yet. Check if we need to open or close the
+ // scope stack.
+ if (symbolOpensScope(begin->kind())) {
+ // We can use the end offset of the scope to determine whether or not
+ // we can just outright skip this entire scope.
+ uint32_t scope_end = getScopeEndOffset(*begin);
+ if (scope_end < id.modi) {
+ begin = syms.at(scope_end);
+ } else {
+ // The symbol we're looking for is somewhere in this scope.
+ scope_stack.emplace_back(id.modi, begin.offset());
+ }
+ } else if (symbolEndsScope(begin->kind())) {
+ scope_stack.pop_back();
+ }
+ ++begin;
+ }
+
+ return llvm::None;
+}
+
+static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) {
+ switch (cr.Kind) {
+ case TypeRecordKind::Class:
+ return clang::TTK_Class;
+ case TypeRecordKind::Struct:
+ return clang::TTK_Struct;
+ case TypeRecordKind::Union:
+ return clang::TTK_Union;
+ case TypeRecordKind::Interface:
+ return clang::TTK_Interface;
+ case TypeRecordKind::Enum:
+ return clang::TTK_Enum;
+ default:
+ lldbassert(false && "Invalid tag record kind!");
+ return clang::TTK_Struct;
+ }
+}
+
+static bool IsCVarArgsFunction(llvm::ArrayRef<TypeIndex> args) {
+ if (args.empty())
+ return false;
+ return args.back() == TypeIndex::None();
+}
+
+static bool
+AnyScopesHaveTemplateParams(llvm::ArrayRef<llvm::ms_demangle::Node *> scopes) {
+ for (llvm::ms_demangle::Node *n : scopes) {
+ auto *idn = static_cast<llvm::ms_demangle::IdentifierNode *>(n);
+ if (idn->TemplateParams)
+ return true;
+ }
+ return false;
+}
+
+static ClangASTContext &GetClangASTContext(ObjectFile &obj) {
+ TypeSystem *ts =
+ obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ lldbassert(ts);
+ return static_cast<ClangASTContext &>(*ts);
+}
+
+static llvm::Optional<clang::CallingConv>
+TranslateCallingConvention(llvm::codeview::CallingConvention conv) {
+ using CC = llvm::codeview::CallingConvention;
+ switch (conv) {
+
+ case CC::NearC:
+ case CC::FarC:
+ return clang::CallingConv::CC_C;
+ case CC::NearPascal:
+ case CC::FarPascal:
+ return clang::CallingConv::CC_X86Pascal;
+ case CC::NearFast:
+ case CC::FarFast:
+ return clang::CallingConv::CC_X86FastCall;
+ case CC::NearStdCall:
+ case CC::FarStdCall:
+ return clang::CallingConv::CC_X86StdCall;
+ case CC::ThisCall:
+ return clang::CallingConv::CC_X86ThisCall;
+ case CC::NearVector:
+ return clang::CallingConv::CC_X86VectorCall;
+ default:
+ return llvm::None;
+ }
+}
+
+static llvm::Optional<CVTagRecord>
+GetNestedTagDefinition(const NestedTypeRecord &Record,
+ const CVTagRecord &parent, TpiStream &tpi) {
+ // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it
+ // is also used to indicate the primary definition of a nested class. That is
+ // to say, if you have:
+ // struct A {
+ // struct B {};
+ // using C = B;
+ // };
+ // Then in the debug info, this will appear as:
+ // LF_STRUCTURE `A::B` [type index = N]
+ // LF_STRUCTURE `A`
+ // LF_NESTTYPE [name = `B`, index = N]
+ // LF_NESTTYPE [name = `C`, index = N]
+ // In order to accurately reconstruct the decl context hierarchy, we need to
+ // know which ones are actual definitions and which ones are just aliases.
+
+ // If it's a simple type, then this is something like `using foo = int`.
+ if (Record.Type.isSimple())
+ return llvm::None;
+
+ CVType cvt = tpi.getType(Record.Type);
+
+ if (!IsTagRecord(cvt))
+ return llvm::None;
+
+ // If it's an inner definition, then treat whatever name we have here as a
+ // single component of a mangled name. So we can inject it into the parent's
+ // mangled name to see if it matches.
+ CVTagRecord child = CVTagRecord::create(cvt);
+ std::string qname = parent.asTag().getUniqueName();
+ if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4)
+ return llvm::None;
+
+ // qname[3] is the tag type identifier (struct, class, union, etc). Since the
+ // inner tag type is not necessarily the same as the outer tag type, re-write
+ // it to match the inner tag type.
+ qname[3] = child.asTag().getUniqueName()[3];
+ std::string piece;
+ if (qname[3] == 'W')
+ piece = "4";
+ piece += Record.Name;
+ piece.push_back('@');
+ qname.insert(4, std::move(piece));
+ if (qname != child.asTag().UniqueName)
+ return llvm::None;
+
+ return std::move(child);
+}
+
+PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index)
+ : m_index(index), m_clang(GetClangASTContext(obj)) {
+ BuildParentMap();
+}
+
+clang::DeclContext &PdbAstBuilder::GetTranslationUnitDecl() {
+ return *m_clang.GetTranslationUnitDecl();
+}
+
+std::pair<clang::DeclContext *, std::string>
+PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) {
+ // FIXME: Move this to GetDeclContextContainingUID.
+ if (!record.hasUniqueName())
+ return CreateDeclInfoForUndecoratedName(record.Name);
+
+ llvm::ms_demangle::Demangler demangler;
+ StringView sv(record.UniqueName.begin(), record.UniqueName.size());
+ llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
+ if (demangler.Error)
+ return {m_clang.GetTranslationUnitDecl(), record.UniqueName};
+
+ llvm::ms_demangle::IdentifierNode *idn =
+ ttn->QualifiedName->getUnqualifiedIdentifier();
+ std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier);
+
+ llvm::ms_demangle::NodeArrayNode *name_components =
+ ttn->QualifiedName->Components;
+ llvm::ArrayRef<llvm::ms_demangle::Node *> scopes(name_components->Nodes,
+ name_components->Count - 1);
+
+ clang::DeclContext *context = m_clang.GetTranslationUnitDecl();
+
+ // If this type doesn't have a parent type in the debug info, then the best we
+ // can do is to say that it's either a series of namespaces (if the scope is
+ // non-empty), or the translation unit (if the scope is empty).
+ auto parent_iter = m_parent_types.find(ti);
+ if (parent_iter == m_parent_types.end()) {
+ if (scopes.empty())
+ return {context, uname};
+
+ // If there is no parent in the debug info, but some of the scopes have
+ // template params, then this is a case of bad debug info. See, for
+ // example, llvm.org/pr39607. We don't want to create an ambiguity between
+ // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at
+ // global scope with the fully qualified name.
+ if (AnyScopesHaveTemplateParams(scopes))
+ return {context, record.Name};
+
+ for (llvm::ms_demangle::Node *scope : scopes) {
+ auto *nii = static_cast<llvm::ms_demangle::NamedIdentifierNode *>(scope);
+ std::string str = nii->toString();
+ context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context);
+ }
+ return {context, uname};
+ }
+
+ // Otherwise, all we need to do is get the parent type of this type and
+ // recurse into our lazy type creation / AST reconstruction logic to get an
+ // LLDB TypeSP for the parent. This will cause the AST to automatically get
+ // the right DeclContext created for any parent.
+ clang::QualType parent_qt = GetOrCreateType(parent_iter->second);
+
+ context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl());
+ return {context, uname};
+}
+
+void PdbAstBuilder::BuildParentMap() {
+ LazyRandomTypeCollection &types = m_index.tpi().typeCollection();
+
+ llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full;
+ llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward;
+
+ struct RecordIndices {
+ TypeIndex forward;
+ TypeIndex full;
+ };
+
+ llvm::StringMap<RecordIndices> record_indices;
+
+ for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
+ CVType type = types.getType(*ti);
+ if (!IsTagRecord(type))
+ continue;
+
+ CVTagRecord tag = CVTagRecord::create(type);
+
+ RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
+ if (tag.asTag().isForwardRef())
+ indices.forward = *ti;
+ else
+ indices.full = *ti;
+
+ if (indices.full != TypeIndex::None() &&
+ indices.forward != TypeIndex::None()) {
+ forward_to_full[indices.forward] = indices.full;
+ full_to_forward[indices.full] = indices.forward;
+ }
+
+ // We're looking for LF_NESTTYPE records in the field list, so ignore
+ // forward references (no field list), and anything without a nested class
+ // (since there won't be any LF_NESTTYPE records).
+ if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass())
+ continue;
+
+ struct ProcessTpiStream : public TypeVisitorCallbacks {
+ ProcessTpiStream(PdbIndex &index, TypeIndex parent,
+ const CVTagRecord &parent_cvt,
+ llvm::DenseMap<TypeIndex, TypeIndex> &parents)
+ : index(index), parents(parents), parent(parent),
+ parent_cvt(parent_cvt) {}
+
+ PdbIndex &index;
+ llvm::DenseMap<TypeIndex, TypeIndex> &parents;
+
+ unsigned unnamed_type_index = 1;
+ TypeIndex parent;
+ const CVTagRecord &parent_cvt;
+
+ llvm::Error visitKnownMember(CVMemberRecord &CVR,
+ NestedTypeRecord &Record) override {
+ std::string unnamed_type_name;
+ if (Record.Name.empty()) {
+ unnamed_type_name =
+ llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str();
+ Record.Name = unnamed_type_name;
+ ++unnamed_type_index;
+ }
+ llvm::Optional<CVTagRecord> tag =
+ GetNestedTagDefinition(Record, parent_cvt, index.tpi());
+ if (!tag)
+ return llvm::ErrorSuccess();
+
+ parents[Record.Type] = parent;
+ return llvm::ErrorSuccess();
+ }
+ };
+
+ CVType field_list = m_index.tpi().getType(tag.asTag().FieldList);
+ ProcessTpiStream process(m_index, *ti, tag, m_parent_types);
+ llvm::Error error = visitMemberRecordStream(field_list.data(), process);
+ if (error)
+ llvm::consumeError(std::move(error));
+ }
+
+ // Now that we know the forward -> full mapping of all type indices, we can
+ // re-write all the indices. At the end of this process, we want a mapping
+ // consisting of fwd -> full and full -> full for all child -> parent indices.
+ // We can re-write the values in place, but for the keys, we must save them
+ // off so that we don't modify the map in place while also iterating it.
+ std::vector<TypeIndex> full_keys;
+ std::vector<TypeIndex> fwd_keys;
+ for (auto &entry : m_parent_types) {
+ TypeIndex key = entry.first;
+ TypeIndex value = entry.second;
+
+ auto iter = forward_to_full.find(value);
+ if (iter != forward_to_full.end())
+ entry.second = iter->second;
+
+ iter = forward_to_full.find(key);
+ if (iter != forward_to_full.end())
+ fwd_keys.push_back(key);
+ else
+ full_keys.push_back(key);
+ }
+ for (TypeIndex fwd : fwd_keys) {
+ TypeIndex full = forward_to_full[fwd];
+ m_parent_types[full] = m_parent_types[fwd];
+ }
+ for (TypeIndex full : full_keys) {
+ TypeIndex fwd = full_to_forward[full];
+ m_parent_types[fwd] = m_parent_types[full];
+ }
+
+ // Now that
+}
+
+static bool isLocalVariableType(SymbolKind K) {
+ switch (K) {
+ case S_REGISTER:
+ case S_REGREL32:
+ case S_LOCAL:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+static std::string
+RenderScopeList(llvm::ArrayRef<llvm::ms_demangle::Node *> nodes) {
+ lldbassert(!nodes.empty());
+
+ std::string result = nodes.front()->toString();
+ nodes = nodes.drop_front();
+ while (!nodes.empty()) {
+ result += "::";
+ result += nodes.front()->toString(llvm::ms_demangle::OF_NoTagSpecifier);
+ nodes = nodes.drop_front();
+ }
+ return result;
+}
+
+static llvm::Optional<PublicSym32> FindPublicSym(const SegmentOffset &addr,
+ SymbolStream &syms,
+ PublicsStream &publics) {
+ llvm::FixedStreamArray<ulittle32_t> addr_map = publics.getAddressMap();
+ auto iter = std::lower_bound(
+ addr_map.begin(), addr_map.end(), addr,
+ [&](const ulittle32_t &x, const SegmentOffset &y) {
+ CVSymbol s1 = syms.readRecord(x);
+ lldbassert(s1.kind() == S_PUB32);
+ PublicSym32 p1;
+ llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(s1, p1));
+ if (p1.Segment < y.segment)
+ return true;
+ return p1.Offset < y.offset;
+ });
+ if (iter == addr_map.end())
+ return llvm::None;
+ CVSymbol sym = syms.readRecord(*iter);
+ lldbassert(sym.kind() == S_PUB32);
+ PublicSym32 p;
+ llvm::cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(sym, p));
+ if (p.Segment == addr.segment && p.Offset == addr.offset)
+ return p;
+ return llvm::None;
+}
+
+clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) {
+ CVSymbol cvs = m_index.ReadSymbolRecord(id);
+
+ if (isLocalVariableType(cvs.kind())) {
+ clang::DeclContext *scope = GetParentDeclContext(id);
+ clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope);
+ PdbCompilandSymId scope_id(id.modi, m_decl_to_status[scope_decl].uid);
+ return GetOrCreateVariableDecl(scope_id, id);
+ }
+
+ switch (cvs.kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ return GetOrCreateFunctionDecl(id);
+ case S_GDATA32:
+ case S_LDATA32:
+ case S_GTHREAD32:
+ case S_CONSTANT:
+ // global variable
+ return nullptr;
+ case S_BLOCK32:
+ return GetOrCreateBlockDecl(id);
+ default:
+ return nullptr;
+ }
+}
+
+clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) {
+ if (clang::Decl *result = TryGetDecl(uid))
+ return result;
+
+ clang::Decl *result = nullptr;
+ switch (uid.kind()) {
+ case PdbSymUidKind::CompilandSym:
+ result = GetOrCreateSymbolForId(uid.asCompilandSym());
+ break;
+ case PdbSymUidKind::Type: {
+ clang::QualType qt = GetOrCreateType(uid.asTypeSym());
+ if (auto *tag = qt->getAsTagDecl()) {
+ result = tag;
+ break;
+ }
+ return nullptr;
+ }
+ default:
+ return nullptr;
+ }
+ m_uid_to_decl[toOpaqueUid(uid)] = result;
+ return result;
+}
+
+clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) {
+ if (uid.kind() == PdbSymUidKind::CompilandSym) {
+ if (uid.asCompilandSym().offset == 0)
+ return &GetTranslationUnitDecl();
+ }
+
+ clang::Decl *decl = GetOrCreateDeclForUid(uid);
+ if (!decl)
+ return nullptr;
+
+ return clang::Decl::castToDeclContext(decl);
+}
+
+std::pair<clang::DeclContext *, std::string>
+PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) {
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+ clang::DeclContext *context = &GetTranslationUnitDecl();
+
+ llvm::StringRef uname = specs.back().GetBaseName();
+ specs = specs.drop_back();
+ if (specs.empty())
+ return {context, name};
+
+ llvm::StringRef scope_name = specs.back().GetFullName();
+
+ // It might be a class name, try that first.
+ std::vector<TypeIndex> types = m_index.tpi().findRecordsByName(scope_name);
+ while (!types.empty()) {
+ clang::QualType qt = GetOrCreateType(types.back());
+ clang::TagDecl *tag = qt->getAsTagDecl();
+ if (tag)
+ return {clang::TagDecl::castToDeclContext(tag), uname};
+ types.pop_back();
+ }
+
+ // If that fails, treat it as a series of namespaces.
+ for (const MSVCUndecoratedNameSpecifier &spec : specs) {
+ std::string ns_name = spec.GetBaseName().str();
+ context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context);
+ }
+ return {context, uname};
+}
+
+clang::DeclContext *
+PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) {
+ if (!SymbolHasAddress(sym))
+ return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
+ SegmentOffset addr = GetSegmentAndOffset(sym);
+ llvm::Optional<PublicSym32> pub =
+ FindPublicSym(addr, m_index.symrecords(), m_index.publics());
+ if (!pub)
+ return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first;
+
+ llvm::ms_demangle::Demangler demangler;
+ StringView name{pub->Name.begin(), pub->Name.size()};
+ llvm::ms_demangle::SymbolNode *node = demangler.parse(name);
+ if (!node)
+ return &GetTranslationUnitDecl();
+ llvm::ArrayRef<llvm::ms_demangle::Node *> name_components{
+ node->Name->Components->Nodes, node->Name->Components->Count - 1};
+
+ if (!name_components.empty()) {
+ // Render the current list of scope nodes as a fully qualified name, and
+ // look it up in the debug info as a type name. If we find something,
+ // this is a type (which may itself be prefixed by a namespace). If we
+ // don't, this is a list of namespaces.
+ std::string qname = RenderScopeList(name_components);
+ std::vector<TypeIndex> matches = m_index.tpi().findRecordsByName(qname);
+ while (!matches.empty()) {
+ clang::QualType qt = GetOrCreateType(matches.back());
+ clang::TagDecl *tag = qt->getAsTagDecl();
+ if (tag)
+ return clang::TagDecl::castToDeclContext(tag);
+ matches.pop_back();
+ }
+ }
+
+ // It's not a type. It must be a series of namespaces.
+ clang::DeclContext *context = &GetTranslationUnitDecl();
+ while (!name_components.empty()) {
+ std::string ns = name_components.front()->toString();
+ context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context);
+ name_components = name_components.drop_front();
+ }
+ return context;
+}
+
+clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) {
+ // We must do this *without* calling GetOrCreate on the current uid, as
+ // that would be an infinite recursion.
+ switch (uid.kind()) {
+ case PdbSymUidKind::CompilandSym: {
+ llvm::Optional<PdbCompilandSymId> scope =
+ FindSymbolScope(m_index, uid.asCompilandSym());
+ if (scope)
+ return GetOrCreateDeclContextForUid(*scope);
+
+ CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym());
+ return GetParentDeclContextForSymbol(sym);
+ }
+ case PdbSymUidKind::Type: {
+ // It could be a namespace, class, or global. We don't support nested
+ // functions yet. Anyway, we just need to consult the parent type map.
+ PdbTypeSymId type_id = uid.asTypeSym();
+ auto iter = m_parent_types.find(type_id.index);
+ if (iter == m_parent_types.end())
+ return &GetTranslationUnitDecl();
+ return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second));
+ }
+ case PdbSymUidKind::FieldListMember:
+ // In this case the parent DeclContext is the one for the class that this
+ // member is inside of.
+ break;
+ case PdbSymUidKind::GlobalSym: {
+ // If this refers to a compiland symbol, just recurse in with that symbol.
+ // The only other possibilities are S_CONSTANT and S_UDT, in which case we
+ // need to parse the undecorated name to figure out the scope, then look
+ // that up in the TPI stream. If it's found, it's a type, othewrise it's
+ // a series of namespaces.
+ // FIXME: do this.
+ CVSymbol global = m_index.ReadSymbolRecord(uid.asGlobalSym());
+ switch (global.kind()) {
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32:
+ return GetParentDeclContextForSymbol(global);
+ case SymbolKind::S_PROCREF:
+ case SymbolKind::S_LPROCREF: {
+ ProcRefSym ref{global.kind()};
+ llvm::cantFail(
+ SymbolDeserializer::deserializeAs<ProcRefSym>(global, ref));
+ PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset};
+ return GetParentDeclContext(cu_sym_id);
+ }
+ case SymbolKind::S_CONSTANT:
+ case SymbolKind::S_UDT:
+ return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return &GetTranslationUnitDecl();
+}
+
+bool PdbAstBuilder::CompleteType(clang::QualType qt) {
+ clang::TagDecl *tag = qt->getAsTagDecl();
+ if (!tag)
+ return false;
+
+ return CompleteTagDecl(*tag);
+}
+
+bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) {
+ // If this is not in our map, it's an error.
+ auto status_iter = m_decl_to_status.find(&tag);
+ lldbassert(status_iter != m_decl_to_status.end());
+
+ // If it's already complete, just return.
+ DeclStatus &status = status_iter->second;
+ if (status.resolved)
+ return true;
+
+ PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym();
+
+ lldbassert(IsTagRecord(type_id, m_index.tpi()));
+
+ clang::QualType tag_qt = m_clang.getASTContext()->getTypeDeclType(&tag);
+ ClangASTContext::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false);
+
+ TypeIndex tag_ti = type_id.index;
+ CVType cvt = m_index.tpi().getType(tag_ti);
+ if (cvt.kind() == LF_MODIFIER)
+ tag_ti = LookThroughModifierRecord(cvt);
+
+ PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, m_index.tpi());
+ cvt = m_index.tpi().getType(best_ti.index);
+ lldbassert(IsTagRecord(cvt));
+
+ if (IsForwardRefUdt(cvt)) {
+ // If we can't find a full decl for this forward ref anywhere in the debug
+ // info, then we have no way to complete it.
+ return false;
+ }
+
+ TypeIndex field_list_ti = GetFieldListIndex(cvt);
+ CVType field_list_cvt = m_index.tpi().getType(field_list_ti);
+ if (field_list_cvt.kind() != LF_FIELDLIST)
+ return false;
+
+ // Visit all members of this class, then perform any finalization necessary
+ // to complete the class.
+ CompilerType ct = ToCompilerType(tag_qt);
+ UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index.tpi());
+ auto error =
+ llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer);
+ completer.complete();
+
+ status.resolved = true;
+ if (!error)
+ return true;
+
+ llvm::consumeError(std::move(error));
+ return false;
+}
+
+clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) {
+ if (ti == TypeIndex::NullptrT())
+ return GetBasicType(lldb::eBasicTypeNullPtr);
+
+ if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
+ clang::QualType direct_type = GetOrCreateType(ti.makeDirect());
+ return m_clang.getASTContext()->getPointerType(direct_type);
+ }
+
+ if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
+ return {};
+
+ lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind());
+ if (bt == lldb::eBasicTypeInvalid)
+ return {};
+
+ return GetBasicType(bt);
+}
+
+clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) {
+ clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType);
+
+ // This can happen for pointers to LF_VTSHAPE records, which we shouldn't
+ // create in the AST.
+ if (pointee_type.isNull())
+ return {};
+
+ if (pointer.isPointerToMember()) {
+ MemberPointerInfo mpi = pointer.getMemberInfo();
+ clang::QualType class_type = GetOrCreateType(mpi.ContainingType);
+
+ return m_clang.getASTContext()->getMemberPointerType(
+ pointee_type, class_type.getTypePtr());
+ }
+
+ clang::QualType pointer_type;
+ if (pointer.getMode() == PointerMode::LValueReference)
+ pointer_type =
+ m_clang.getASTContext()->getLValueReferenceType(pointee_type);
+ else if (pointer.getMode() == PointerMode::RValueReference)
+ pointer_type =
+ m_clang.getASTContext()->getRValueReferenceType(pointee_type);
+ else
+ pointer_type = m_clang.getASTContext()->getPointerType(pointee_type);
+
+ if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None)
+ pointer_type.addConst();
+
+ if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None)
+ pointer_type.addVolatile();
+
+ if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None)
+ pointer_type.addRestrict();
+
+ return pointer_type;
+}
+
+clang::QualType
+PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) {
+ clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType);
+ if (unmodified_type.isNull())
+ return {};
+
+ if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None)
+ unmodified_type.addConst();
+ if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None)
+ unmodified_type.addVolatile();
+
+ return unmodified_type;
+}
+
+clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id,
+ const TagRecord &record) {
+ clang::DeclContext *context = nullptr;
+ std::string uname;
+ std::tie(context, uname) = CreateDeclInfoForType(record, id.index);
+ clang::TagTypeKind ttk = TranslateUdtKind(record);
+ lldb::AccessType access =
+ (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic;
+
+ ClangASTMetadata metadata;
+ metadata.SetUserID(toOpaqueUid(id));
+ metadata.SetIsDynamicCXXType(false);
+
+ CompilerType ct =
+ m_clang.CreateRecordType(context, access, uname.c_str(), ttk,
+ lldb::eLanguageTypeC_plus_plus, &metadata);
+
+ lldbassert(ct.IsValid());
+
+ ClangASTContext::StartTagDeclarationDefinition(ct);
+
+ // Even if it's possible, don't complete it at this point. Just mark it
+ // forward resolved, and if/when LLDB needs the full definition, it can
+ // ask us.
+ clang::QualType result =
+ clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+
+ ClangASTContext::SetHasExternalStorage(result.getAsOpaquePtr(), true);
+ return result;
+}
+
+clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
+ auto iter = m_uid_to_decl.find(toOpaqueUid(uid));
+ if (iter != m_uid_to_decl.end())
+ return iter->second;
+ return nullptr;
+}
+
+clang::NamespaceDecl *
+PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name,
+ clang::DeclContext &context) {
+ return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context);
+}
+
+clang::BlockDecl *
+PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) {
+ if (clang::Decl *decl = TryGetDecl(block_id))
+ return llvm::dyn_cast<clang::BlockDecl>(decl);
+
+ clang::DeclContext *scope = GetParentDeclContext(block_id);
+
+ clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope);
+ m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl});
+
+ DeclStatus status;
+ status.resolved = true;
+ status.uid = toOpaqueUid(block_id);
+ m_decl_to_status.insert({block_decl, status});
+
+ return block_decl;
+}
+
+clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym,
+ clang::DeclContext &scope) {
+ VariableInfo var_info = GetVariableNameInfo(sym);
+ clang::QualType qt = GetOrCreateType(var_info.type);
+
+ clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration(
+ &scope, var_info.name.str().c_str(), qt);
+
+ m_uid_to_decl[toOpaqueUid(uid)] = var_decl;
+ DeclStatus status;
+ status.resolved = true;
+ status.uid = toOpaqueUid(uid);
+ m_decl_to_status.insert({var_decl, status});
+ return var_decl;
+}
+
+clang::VarDecl *
+PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
+ PdbCompilandSymId var_id) {
+ if (clang::Decl *decl = TryGetDecl(var_id))
+ return llvm::dyn_cast<clang::VarDecl>(decl);
+
+ clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id);
+
+ CVSymbol sym = m_index.ReadSymbolRecord(var_id);
+ return CreateVariableDecl(PdbSymUid(var_id), sym, *scope);
+}
+
+clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) {
+ if (clang::Decl *decl = TryGetDecl(var_id))
+ return llvm::dyn_cast<clang::VarDecl>(decl);
+
+ CVSymbol sym = m_index.ReadSymbolRecord(var_id);
+ return CreateVariableDecl(PdbSymUid(var_id), sym, GetTranslationUnitDecl());
+}
+
+clang::TypedefNameDecl *
+PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) {
+ if (clang::Decl *decl = TryGetDecl(id))
+ return llvm::dyn_cast<clang::TypedefNameDecl>(decl);
+
+ CVSymbol sym = m_index.ReadSymbolRecord(id);
+ lldbassert(sym.kind() == S_UDT);
+ UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+
+ clang::DeclContext *scope = GetParentDeclContext(id);
+
+ PdbTypeSymId real_type_id{udt.Type, false};
+ clang::QualType qt = GetOrCreateType(real_type_id);
+
+ std::string uname = DropNameScope(udt.Name);
+
+ CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(),
+ ToCompilerDeclContext(*scope));
+ clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct);
+ DeclStatus status;
+ status.resolved = true;
+ status.uid = toOpaqueUid(id);
+ m_decl_to_status.insert({tnd, status});
+ return tnd;
+}
+
+clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) {
+ CompilerType ct = m_clang.GetBasicType(type);
+ return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType());
+}
+
+clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) {
+ if (type.index.isSimple())
+ return CreateSimpleType(type.index);
+
+ CVType cvt = m_index.tpi().getType(type.index);
+
+ if (cvt.kind() == LF_MODIFIER) {
+ ModifierRecord modifier;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
+ return CreateModifierType(modifier);
+ }
+
+ if (cvt.kind() == LF_POINTER) {
+ PointerRecord pointer;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
+ return CreatePointerType(pointer);
+ }
+
+ if (IsTagRecord(cvt)) {
+ CVTagRecord tag = CVTagRecord::create(cvt);
+ if (tag.kind() == CVTagRecord::Union)
+ return CreateRecordType(type.index, tag.asUnion());
+ if (tag.kind() == CVTagRecord::Enum)
+ return CreateEnumType(type.index, tag.asEnum());
+ return CreateRecordType(type.index, tag.asClass());
+ }
+
+ if (cvt.kind() == LF_ARRAY) {
+ ArrayRecord ar;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
+ return CreateArrayType(ar);
+ }
+
+ if (cvt.kind() == LF_PROCEDURE) {
+ ProcedureRecord pr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
+ return CreateProcedureType(pr);
+ }
+
+ return {};
+}
+
+clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) {
+ lldb::user_id_t uid = toOpaqueUid(type);
+ auto iter = m_uid_to_type.find(uid);
+ if (iter != m_uid_to_type.end())
+ return iter->second;
+
+ PdbTypeSymId best_type = GetBestPossibleDecl(type, m_index.tpi());
+
+ clang::QualType qt;
+ if (best_type.index != type.index) {
+ // This is a forward decl. Call GetOrCreate on the full decl, then map the
+ // forward decl id to the full decl QualType.
+ clang::QualType qt = GetOrCreateType(best_type);
+ m_uid_to_type[toOpaqueUid(type)] = qt;
+ return qt;
+ }
+
+ // This is either a full decl, or a forward decl with no matching full decl
+ // in the debug info.
+ qt = CreateType(type);
+ m_uid_to_type[toOpaqueUid(type)] = qt;
+ if (IsTagRecord(type, m_index.tpi())) {
+ clang::TagDecl *tag = qt->getAsTagDecl();
+ lldbassert(m_decl_to_status.count(tag) == 0);
+
+ DeclStatus &status = m_decl_to_status[tag];
+ status.uid = uid;
+ status.resolved = false;
+ }
+ return qt;
+}
+
+clang::FunctionDecl *
+PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) {
+ if (clang::Decl *decl = TryGetDecl(func_id))
+ return llvm::dyn_cast<clang::FunctionDecl>(decl);
+
+ clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id));
+ std::string context_name;
+ if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) {
+ context_name = ns->getQualifiedNameAsString();
+ } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) {
+ context_name = tag->getQualifiedNameAsString();
+ }
+
+ CVSymbol cvs = m_index.ReadSymbolRecord(func_id);
+ ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind()));
+ llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc));
+
+ PdbTypeSymId type_id(proc.FunctionType);
+ clang::QualType qt = GetOrCreateType(type_id);
+ if (qt.isNull())
+ return nullptr;
+
+ clang::StorageClass storage = clang::SC_None;
+ if (proc.Kind == SymbolRecordKind::ProcSym)
+ storage = clang::SC_Static;
+
+ const clang::FunctionProtoType *func_type =
+ llvm::dyn_cast<clang::FunctionProtoType>(qt);
+
+ CompilerType func_ct = ToCompilerType(qt);
+
+ llvm::StringRef proc_name = proc.Name;
+ proc_name.consume_front(context_name);
+ proc_name.consume_front("::");
+
+ clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration(
+ parent, proc_name.str().c_str(), func_ct, storage, false);
+
+ lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
+ m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
+ DeclStatus status;
+ status.resolved = true;
+ status.uid = toOpaqueUid(func_id);
+ m_decl_to_status.insert({function_decl, status});
+
+ CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams());
+
+ return function_decl;
+}
+
+void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
+ clang::FunctionDecl &function_decl,
+ uint32_t param_count) {
+ CompilandIndexItem *cii = m_index.compilands().GetCompiland(func_id.modi);
+ CVSymbolArray scope =
+ cii->m_debug_stream.getSymbolArrayForScope(func_id.offset);
+
+ auto begin = scope.begin();
+ auto end = scope.end();
+ std::vector<clang::ParmVarDecl *> params;
+ while (begin != end && param_count > 0) {
+ uint32_t record_offset = begin.offset();
+ CVSymbol sym = *begin++;
+
+ TypeIndex param_type;
+ llvm::StringRef param_name;
+ switch (sym.kind()) {
+ case S_REGREL32: {
+ RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
+ param_type = reg.Type;
+ param_name = reg.Name;
+ break;
+ }
+ case S_REGISTER: {
+ RegisterSym reg(SymbolRecordKind::RegisterSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
+ param_type = reg.Index;
+ param_name = reg.Name;
+ break;
+ }
+ case S_LOCAL: {
+ LocalSym local(SymbolRecordKind::LocalSym);
+ cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
+ if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)
+ continue;
+ param_type = local.Type;
+ param_name = local.Name;
+ break;
+ }
+ case S_BLOCK32:
+ // All parameters should come before the first block. If that isn't the
+ // case, then perhaps this is bad debug info that doesn't contain
+ // information about all parameters.
+ return;
+ default:
+ continue;
+ }
+
+ PdbCompilandSymId param_uid(func_id.modi, record_offset);
+ clang::QualType qt = GetOrCreateType(param_type);
+
+ CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr());
+ clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
+ &function_decl, param_name.str().c_str(), param_type_ct,
+ clang::SC_None);
+ lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
+
+ m_uid_to_decl[toOpaqueUid(param_uid)] = param;
+ params.push_back(param);
+ --param_count;
+ }
+
+ if (!params.empty())
+ m_clang.SetFunctionParameters(&function_decl, params.data(), params.size());
+}
+
+clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
+ const EnumRecord &er) {
+ clang::DeclContext *decl_context = nullptr;
+ std::string uname;
+ std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index);
+ clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType);
+
+ Declaration declaration;
+ CompilerType enum_ct = m_clang.CreateEnumerationType(
+ uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type),
+ er.isScoped());
+
+ ClangASTContext::StartTagDeclarationDefinition(enum_ct);
+ ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true);
+
+ return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType());
+}
+
+clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
+ clang::QualType element_type = GetOrCreateType(ar.ElementType);
+
+ uint64_t element_count =
+ ar.Size / GetSizeOfType({ar.ElementType}, m_index.tpi());
+
+ CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type),
+ element_count, false);
+ return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType());
+}
+
+clang::QualType
+PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) {
+ TpiStream &stream = m_index.tpi();
+ CVType args_cvt = stream.getType(proc.ArgumentList);
+ ArgListRecord args;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<ArgListRecord>(args_cvt, args));
+
+ llvm::ArrayRef<TypeIndex> arg_indices = llvm::makeArrayRef(args.ArgIndices);
+ bool is_variadic = IsCVarArgsFunction(arg_indices);
+ if (is_variadic)
+ arg_indices = arg_indices.drop_back();
+
+ std::vector<CompilerType> arg_types;
+ arg_types.reserve(arg_indices.size());
+
+ for (TypeIndex arg_index : arg_indices) {
+ clang::QualType arg_type = GetOrCreateType(arg_index);
+ arg_types.push_back(ToCompilerType(arg_type));
+ }
+
+ clang::QualType return_type = GetOrCreateType(proc.ReturnType);
+
+ llvm::Optional<clang::CallingConv> cc =
+ TranslateCallingConvention(proc.CallConv);
+ if (!cc)
+ return {};
+
+ CompilerType return_ct = ToCompilerType(return_type);
+ CompilerType func_sig_ast_type = m_clang.CreateFunctionType(
+ return_ct, arg_types.data(), arg_types.size(), is_variadic, 0, *cc);
+
+ return clang::QualType::getFromOpaquePtr(
+ func_sig_ast_type.GetOpaqueQualType());
+}
+
+static bool isTagDecl(clang::DeclContext &context) {
+ return !!llvm::dyn_cast<clang::TagDecl>(&context);
+}
+
+static bool isFunctionDecl(clang::DeclContext &context) {
+ return !!llvm::dyn_cast<clang::FunctionDecl>(&context);
+}
+
+static bool isBlockDecl(clang::DeclContext &context) {
+ return !!llvm::dyn_cast<clang::BlockDecl>(&context);
+}
+
+void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf(
+ llvm::Optional<llvm::StringRef> parent) {
+ TypeIndex ti{m_index.tpi().TypeIndexBegin()};
+ for (const CVType &cvt : m_index.tpi().typeArray()) {
+ PdbTypeSymId tid{ti};
+ ++ti;
+
+ if (!IsTagRecord(cvt))
+ continue;
+
+ CVTagRecord tag = CVTagRecord::create(cvt);
+
+ if (!parent.hasValue()) {
+ clang::QualType qt = GetOrCreateType(tid);
+ CompleteType(qt);
+ continue;
+ }
+
+ // Call CreateDeclInfoForType unconditionally so that the namespace info
+ // gets created. But only call CreateRecordType if the namespace name
+ // matches.
+ clang::DeclContext *context = nullptr;
+ std::string uname;
+ std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index);
+ if (!context->isNamespace())
+ continue;
+
+ clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(context);
+ std::string actual_ns = ns->getQualifiedNameAsString();
+ if (llvm::StringRef(actual_ns).startswith(*parent)) {
+ clang::QualType qt = GetOrCreateType(tid);
+ CompleteType(qt);
+ continue;
+ }
+ }
+
+ uint32_t module_count = m_index.dbi().modules().getModuleCount();
+ for (uint16_t modi = 0; modi < module_count; ++modi) {
+ CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(modi);
+ const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray();
+ auto iter = symbols.begin();
+ while (iter != symbols.end()) {
+ PdbCompilandSymId sym_id{modi, iter.offset()};
+
+ switch (iter->kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ GetOrCreateFunctionDecl(sym_id);
+ iter = symbols.at(getScopeEndOffset(*iter));
+ break;
+ case S_GDATA32:
+ case S_GTHREAD32:
+ case S_LDATA32:
+ case S_LTHREAD32:
+ GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id);
+ ++iter;
+ break;
+ default:
+ ++iter;
+ continue;
+ }
+ }
+ }
+}
+
+static CVSymbolArray skipFunctionParameters(clang::Decl &decl,
+ const CVSymbolArray &symbols) {
+ clang::FunctionDecl *func_decl = llvm::dyn_cast<clang::FunctionDecl>(&decl);
+ if (!func_decl)
+ return symbols;
+ unsigned int params = func_decl->getNumParams();
+ if (params == 0)
+ return symbols;
+
+ CVSymbolArray result = symbols;
+
+ while (!result.empty()) {
+ if (params == 0)
+ return result;
+
+ CVSymbol sym = *result.begin();
+ result.drop_front();
+
+ if (!isLocalVariableType(sym.kind()))
+ continue;
+
+ --params;
+ }
+ return result;
+}
+
+void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) {
+ CVSymbol sym = m_index.ReadSymbolRecord(block_id);
+ lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 ||
+ sym.kind() == S_BLOCK32);
+ CompilandIndexItem &cii =
+ m_index.compilands().GetOrCreateCompiland(block_id.modi);
+ CVSymbolArray symbols =
+ cii.m_debug_stream.getSymbolArrayForScope(block_id.offset);
+
+ // Function parameters should already have been created when the function was
+ // parsed.
+ if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32)
+ symbols =
+ skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols);
+
+ auto begin = symbols.begin();
+ while (begin != symbols.end()) {
+ PdbCompilandSymId child_sym_id(block_id.modi, begin.offset());
+ GetOrCreateSymbolForId(child_sym_id);
+ if (begin->kind() == S_BLOCK32) {
+ ParseBlockChildren(child_sym_id);
+ begin = symbols.at(getScopeEndOffset(*begin));
+ }
+ ++begin;
+ }
+}
+
+void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) {
+
+ clang::Decl *decl = clang::Decl::castFromDeclContext(&context);
+ lldbassert(decl);
+
+ auto iter = m_decl_to_status.find(decl);
+ lldbassert(iter != m_decl_to_status.end());
+
+ if (auto *tag = llvm::dyn_cast<clang::TagDecl>(&context)) {
+ CompleteTagDecl(*tag);
+ return;
+ }
+
+ if (isFunctionDecl(context) || isBlockDecl(context)) {
+ PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym();
+ ParseBlockChildren(block_id);
+ }
+}
+
+void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) {
+ // Namespaces aren't explicitly represented in the debug info, and the only
+ // way to parse them is to parse all type info, demangling every single type
+ // and trying to reconstruct the DeclContext hierarchy this way. Since this
+ // is an expensive operation, we have to special case it so that we do other
+ // work (such as parsing the items that appear within the namespaces) at the
+ // same time.
+ if (context.isTranslationUnit()) {
+ ParseAllNamespacesPlusChildrenOf(llvm::None);
+ return;
+ }
+
+ if (context.isNamespace()) {
+ clang::NamespaceDecl &ns = *llvm::dyn_cast<clang::NamespaceDecl>(&context);
+ std::string qname = ns.getQualifiedNameAsString();
+ ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname});
+ return;
+ }
+
+ if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) {
+ ParseDeclsForSimpleContext(context);
+ return;
+ }
+}
+
+CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {
+ return {&m_clang, &decl};
+}
+
+CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {
+ return {&m_clang, qt.getAsOpaquePtr()};
+}
+
+CompilerDeclContext
+PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) {
+ return {&m_clang, &context};
+}
+
+clang::DeclContext *
+PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
+ return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
+}
+
+void PdbAstBuilder::Dump(Stream &stream) { m_clang.Dump(stream); }
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
new file mode 100644
index 000000000000..e3c0346f935e
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -0,0 +1,144 @@
+//===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
+#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+
+#include "lldb/Symbol/ClangASTImporter.h"
+
+#include "PdbIndex.h"
+#include "PdbSymUid.h"
+
+namespace clang {
+class TagDecl;
+class DeclContext;
+class Decl;
+class QualType;
+class FunctionDecl;
+class NamespaceDecl;
+} // namespace clang
+
+namespace llvm {
+namespace codeview {
+class ProcSym;
+}
+} // namespace llvm
+
+namespace lldb_private {
+class ClangASTImporter;
+class ObjectFile;
+
+namespace npdb {
+class PdbIndex;
+struct VariableInfo;
+
+struct DeclStatus {
+ DeclStatus() = default;
+ DeclStatus(lldb::user_id_t uid, bool resolved)
+ : uid(uid), resolved(resolved) {}
+ lldb::user_id_t uid = 0;
+ bool resolved = false;
+};
+
+class PdbAstBuilder {
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ PdbAstBuilder(ObjectFile &obj, PdbIndex &index);
+
+ clang::DeclContext &GetTranslationUnitDecl();
+
+ clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid);
+ clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid);
+ clang::DeclContext *GetParentDeclContext(PdbSymUid uid);
+
+ clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name,
+ clang::DeclContext &context);
+ clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id);
+ clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id);
+ clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id,
+ PdbCompilandSymId var_id);
+ clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id);
+ clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id);
+ void ParseDeclsForContext(clang::DeclContext &context);
+
+ clang::QualType GetBasicType(lldb::BasicType type);
+ clang::QualType GetOrCreateType(PdbTypeSymId type);
+
+ bool CompleteTagDecl(clang::TagDecl &tag);
+ bool CompleteType(clang::QualType qt);
+
+ CompilerDecl ToCompilerDecl(clang::Decl &decl);
+ CompilerType ToCompilerType(clang::QualType qt);
+ CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context);
+ clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context);
+
+ ClangASTContext &clang() { return m_clang; }
+ ClangASTImporter &importer() { return m_importer; }
+
+ void Dump(Stream &stream);
+
+private:
+ clang::Decl *TryGetDecl(PdbSymUid uid) const;
+
+ using TypeIndex = llvm::codeview::TypeIndex;
+
+ clang::QualType
+ CreatePointerType(const llvm::codeview::PointerRecord &pointer);
+ clang::QualType
+ CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
+ clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
+ clang::QualType CreateRecordType(PdbTypeSymId id,
+ const llvm::codeview::TagRecord &record);
+ clang::QualType CreateEnumType(PdbTypeSymId id,
+ const llvm::codeview::EnumRecord &record);
+ clang::QualType
+ CreateProcedureType(const llvm::codeview::ProcedureRecord &proc);
+ clang::QualType CreateType(PdbTypeSymId type);
+
+ void CreateFunctionParameters(PdbCompilandSymId func_id,
+ clang::FunctionDecl &function_decl,
+ uint32_t param_count);
+ clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id);
+ clang::VarDecl *CreateVariableDecl(PdbSymUid uid,
+ llvm::codeview::CVSymbol sym,
+ clang::DeclContext &scope);
+ clang::DeclContext *
+ GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym);
+
+ void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent);
+ void ParseDeclsForSimpleContext(clang::DeclContext &context);
+ void ParseBlockChildren(PdbCompilandSymId block_id);
+
+ void BuildParentMap();
+ std::pair<clang::DeclContext *, std::string>
+ CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti);
+ std::pair<clang::DeclContext *, std::string>
+ CreateDeclInfoForUndecoratedName(llvm::StringRef uname);
+ clang::QualType CreateSimpleType(TypeIndex ti);
+
+ PdbIndex &m_index;
+ ClangASTContext &m_clang;
+
+ ClangASTImporter m_importer;
+
+ llvm::DenseMap<TypeIndex, TypeIndex> m_parent_types;
+ llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status;
+ llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl;
+ llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type;
+};
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
new file mode 100644
index 000000000000..9f5dab6c2e84
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp
@@ -0,0 +1,200 @@
+//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PdbIndex.h"
+#include "PdbUtil.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Error.h"
+
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-defines.h"
+
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+PdbIndex::PdbIndex() : m_cus(*this), m_va_to_modi(m_allocator) {}
+
+#define ASSIGN_PTR_OR_RETURN(result_ptr, expr) \
+ { \
+ auto expected_result = expr; \
+ if (!expected_result) \
+ return expected_result.takeError(); \
+ result_ptr = &expected_result.get(); \
+ }
+
+llvm::Expected<std::unique_ptr<PdbIndex>>
+PdbIndex::create(std::unique_ptr<llvm::pdb::PDBFile> file) {
+ lldbassert(file);
+
+ std::unique_ptr<PdbIndex> result(new PdbIndex());
+ ASSIGN_PTR_OR_RETURN(result->m_dbi, file->getPDBDbiStream());
+ ASSIGN_PTR_OR_RETURN(result->m_tpi, file->getPDBTpiStream());
+ ASSIGN_PTR_OR_RETURN(result->m_ipi, file->getPDBIpiStream());
+ ASSIGN_PTR_OR_RETURN(result->m_info, file->getPDBInfoStream());
+ ASSIGN_PTR_OR_RETURN(result->m_publics, file->getPDBPublicsStream());
+ ASSIGN_PTR_OR_RETURN(result->m_globals, file->getPDBGlobalsStream());
+ ASSIGN_PTR_OR_RETURN(result->m_symrecords, file->getPDBSymbolStream());
+
+ result->m_tpi->buildHashMap();
+
+ result->m_file = std::move(file);
+
+ return std::move(result);
+}
+
+lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment,
+ uint32_t offset) const {
+ // Segment indices are 1-based.
+ lldbassert(segment > 0);
+
+ uint32_t max_section = dbi().getSectionHeaders().size();
+ lldbassert(segment <= max_section + 1);
+
+ // If this is an absolute symbol, it's indicated by the magic section index
+ // |max_section+1|. In this case, the offset is meaningless, so just return.
+ if (segment == max_section + 1)
+ return LLDB_INVALID_ADDRESS;
+
+ const llvm::object::coff_section &cs = dbi().getSectionHeaders()[segment - 1];
+ return m_load_address + static_cast<lldb::addr_t>(cs.VirtualAddress) +
+ static_cast<lldb::addr_t>(offset);
+}
+
+lldb::addr_t PdbIndex::MakeVirtualAddress(const SegmentOffset &so) const {
+ return MakeVirtualAddress(so.segment, so.offset);
+}
+
+llvm::Optional<uint16_t>
+PdbIndex::GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const {
+ return GetModuleIndexForVa(MakeVirtualAddress(segment, offset));
+}
+
+llvm::Optional<uint16_t> PdbIndex::GetModuleIndexForVa(lldb::addr_t va) const {
+ auto iter = m_va_to_modi.find(va);
+ if (iter == m_va_to_modi.end())
+ return llvm::None;
+
+ return iter.value();
+}
+
+void PdbIndex::ParseSectionContribs() {
+ class Visitor : public ISectionContribVisitor {
+ PdbIndex &m_ctx;
+ llvm::IntervalMap<uint64_t, uint16_t> &m_imap;
+
+ public:
+ Visitor(PdbIndex &ctx, llvm::IntervalMap<uint64_t, uint16_t> &imap)
+ : m_ctx(ctx), m_imap(imap) {}
+
+ void visit(const SectionContrib &C) override {
+ if (C.Size == 0)
+ return;
+
+ uint64_t va = m_ctx.MakeVirtualAddress(C.ISect, C.Off);
+ uint64_t end = va + C.Size;
+ // IntervalMap's start and end represent a closed range, not a half-open
+ // range, so we have to subtract 1.
+ m_imap.insert(va, end - 1, C.Imod);
+ }
+ void visit(const SectionContrib2 &C) override { visit(C.Base); }
+ };
+ Visitor v(*this, m_va_to_modi);
+ dbi().visitSectionContributions(v);
+}
+
+void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) {
+ lldbassert(cci.m_symbols_by_va.empty() &&
+ "Addr to symbol map is already built!");
+ uint16_t modi = cci.m_id.modi;
+ const CVSymbolArray &syms = cci.m_debug_stream.getSymbolArray();
+ for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
+ if (!SymbolHasAddress(*iter))
+ continue;
+
+ SegmentOffset so = GetSegmentAndOffset(*iter);
+ lldb::addr_t va = MakeVirtualAddress(so);
+
+ PdbCompilandSymId cu_sym_id(modi, iter.offset());
+
+ // If the debug info is incorrect, we could have multiple symbols with the
+ // same address. So use try_emplace instead of insert, and the first one
+ // will win.
+ cci.m_symbols_by_va.insert(std::make_pair(va, PdbSymUid(cu_sym_id)));
+ }
+}
+
+std::vector<SymbolAndUid> PdbIndex::FindSymbolsByVa(lldb::addr_t va) {
+ std::vector<SymbolAndUid> result;
+
+ llvm::Optional<uint16_t> modi = GetModuleIndexForVa(va);
+ if (!modi)
+ return result;
+
+ CompilandIndexItem &cci = compilands().GetOrCreateCompiland(*modi);
+ if (cci.m_symbols_by_va.empty())
+ BuildAddrToSymbolMap(cci);
+
+ // The map is sorted by starting address of the symbol. So for example
+ // we could (in theory) have this situation
+ //
+ // [------------------]
+ // [----------]
+ // [-----------]
+ // [-------------]
+ // [----]
+ // [-----]
+ // ^ Address we're searching for
+ // In order to find this, we use the upper_bound of the key value which would
+ // be the first symbol whose starting address is higher than the element we're
+ // searching for.
+
+ auto ub = cci.m_symbols_by_va.upper_bound(va);
+
+ for (auto iter = cci.m_symbols_by_va.begin(); iter != ub; ++iter) {
+ PdbCompilandSymId cu_sym_id = iter->second.asCompilandSym();
+ CVSymbol sym = ReadSymbolRecord(cu_sym_id);
+
+ SegmentOffsetLength sol;
+ if (SymbolIsCode(sym))
+ sol = GetSegmentOffsetAndLength(sym);
+ else
+ sol.so = GetSegmentAndOffset(sym);
+
+ lldb::addr_t start = MakeVirtualAddress(sol.so);
+ lldb::addr_t end = start + sol.length;
+ if (va >= start && va < end)
+ result.push_back({std::move(sym), iter->second});
+ }
+
+ return result;
+}
+
+CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const {
+ // We need to subtract 4 here to adjust for the codeview debug magic
+ // at the beginning of the debug info stream.
+ const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi);
+ auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset);
+ lldbassert(iter != cci->m_debug_stream.getSymbolArray().end());
+ return *iter;
+}
+
+CVSymbol PdbIndex::ReadSymbolRecord(PdbGlobalSymId global) const {
+ return symrecords().readRecord(global.offset);
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
new file mode 100644
index 000000000000..839d4e6606e4
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbIndex.h
@@ -0,0 +1,162 @@
+//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H
+#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H
+
+#include "lldb/lldb-types.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include "CompileUnitIndex.h"
+#include "PdbSymUid.h"
+
+#include <map>
+#include <memory>
+
+namespace llvm {
+namespace pdb {
+class DbiStream;
+class TpiStream;
+class TpiStream;
+class InfoStream;
+class PublicsStream;
+class GlobalsStream;
+class SymbolStream;
+} // namespace pdb
+} // namespace llvm
+
+namespace lldb_private {
+namespace npdb {
+struct SegmentOffset;
+
+/// PdbIndex - Lazy access to the important parts of a PDB file.
+///
+/// This is a layer on top of LLVM's native PDB support libraries which cache
+/// certain data when it is accessed the first time. The entire PDB file is
+/// mapped into memory, and the underlying support libraries vend out memory
+/// that is always backed by the file, so it is safe to hold StringRefs and
+/// ArrayRefs into the backing memory as long as the PdbIndex instance is
+/// alive.
+class PdbIndex {
+
+ /// The underlying PDB file.
+ std::unique_ptr<llvm::pdb::PDBFile> m_file;
+
+ /// The DBI stream. This contains general high level information about the
+ /// features present in the PDB file, compile units (such as the information
+ /// necessary to locate full symbol information for each compile unit),
+ /// section contributions, and other data which is not specifically symbol or
+ /// type records.
+ llvm::pdb::DbiStream *m_dbi = nullptr;
+
+ /// TPI (types) and IPI (indices) streams. These are both in the exact same
+ /// format with different data. Most type records are stored in the TPI
+ /// stream but certain specific types of records are stored in the IPI stream.
+ /// The IPI stream records can refer to the records in the TPI stream, but not
+ /// the other way around.
+ llvm::pdb::TpiStream *m_tpi = nullptr;
+ llvm::pdb::TpiStream *m_ipi = nullptr;
+
+ /// This is called the "PDB Stream" in the Microsoft reference implementation.
+ /// It contains information about the structure of the file, as well as fields
+ /// used to match EXE and PDB.
+ llvm::pdb::InfoStream *m_info = nullptr;
+
+ /// Publics stream. Is actually a serialized hash table where the keys are
+ /// addresses of symbols in the executable, and values are a record containing
+ /// mangled names and an index which can be used to locate more detailed info
+ /// about the symbol in the Symbol Records stream. The publics stream only
+ /// contains info about externally visible symbols.
+ llvm::pdb::PublicsStream *m_publics = nullptr;
+
+ /// Globals stream. Contrary to its name, this does not contain information
+ /// about all "global variables" or "global functions". Rather, it is the
+ /// "global symbol table", i.e. it contains information about *every* symbol
+ /// in the executable. It is a hash table keyed on name, whose values are
+ /// indices into the symbol records stream to find the full record.
+ llvm::pdb::GlobalsStream *m_globals = nullptr;
+
+ /// Symbol records stream. The publics and globals stream refer to records
+ /// in this stream. For some records, like constants and typedefs, the
+ /// complete record lives in this stream. For other symbol types, such as
+ /// functions, data, and other things that have been materialied into a
+ /// specific compile unit, the records here simply provide a reference
+ /// necessary to locate the full information.
+ llvm::pdb::SymbolStream *m_symrecords = nullptr;
+
+ /// Index of all compile units, mapping identifier to |CompilandIndexItem|
+ /// instance.
+ CompileUnitIndex m_cus;
+
+ /// An allocator for the interval maps
+ llvm::IntervalMap<lldb::addr_t, uint32_t>::Allocator m_allocator;
+
+ /// Maps virtual address to module index
+ llvm::IntervalMap<lldb::addr_t, uint16_t> m_va_to_modi;
+
+ /// The address at which the program has been loaded into memory.
+ lldb::addr_t m_load_address = 0;
+
+ PdbIndex();
+
+ void BuildAddrToSymbolMap(CompilandIndexItem &cci);
+
+public:
+ static llvm::Expected<std::unique_ptr<PdbIndex>>
+ create(std::unique_ptr<llvm::pdb::PDBFile>);
+
+ void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; }
+ void ParseSectionContribs();
+
+ llvm::pdb::PDBFile &pdb() { return *m_file; }
+ const llvm::pdb::PDBFile &pdb() const { return *m_file; }
+
+ llvm::pdb::DbiStream &dbi() { return *m_dbi; }
+ const llvm::pdb::DbiStream &dbi() const { return *m_dbi; }
+
+ llvm::pdb::TpiStream &tpi() { return *m_tpi; }
+ const llvm::pdb::TpiStream &tpi() const { return *m_tpi; }
+
+ llvm::pdb::TpiStream &ipi() { return *m_ipi; }
+ const llvm::pdb::TpiStream &ipi() const { return *m_ipi; }
+
+ llvm::pdb::InfoStream &info() { return *m_info; }
+ const llvm::pdb::InfoStream &info() const { return *m_info; }
+
+ llvm::pdb::PublicsStream &publics() { return *m_publics; }
+ const llvm::pdb::PublicsStream &publics() const { return *m_publics; }
+
+ llvm::pdb::GlobalsStream &globals() { return *m_globals; }
+ const llvm::pdb::GlobalsStream &globals() const { return *m_globals; }
+
+ llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; }
+ const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; }
+
+ CompileUnitIndex &compilands() { return m_cus; }
+ const CompileUnitIndex &compilands() const { return m_cus; }
+
+ lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const;
+ lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const;
+
+ std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va);
+
+ llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const;
+ llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const;
+
+ llvm::Optional<uint16_t> GetModuleIndexForAddr(uint16_t segment,
+ uint32_t offset) const;
+ llvm::Optional<uint16_t> GetModuleIndexForVa(lldb::addr_t va) const;
+};
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
new file mode 100644
index 000000000000..e5424568da47
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
@@ -0,0 +1,161 @@
+//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PdbSymUid.h"
+
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+
+namespace {
+struct GenericIdRepr {
+ uint64_t tag : 4;
+ uint64_t data : 60;
+};
+
+struct CompilandIdRepr {
+ uint64_t tag : 4;
+ uint64_t modi : 16;
+ uint64_t unused : 44;
+};
+
+struct CompilandSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t modi : 16;
+ uint64_t offset : 32;
+ uint64_t unused : 12;
+};
+
+struct GlobalSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t offset : 32;
+ uint64_t pub : 1;
+ uint64_t unused : 27;
+};
+
+struct TypeSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t index : 32;
+ uint64_t ipi : 1;
+ uint64_t unused : 27;
+};
+
+struct FieldListMemberIdRepr {
+ uint64_t tag : 4;
+ uint64_t index : 32;
+ uint64_t offset : 16;
+ uint64_t unused : 12;
+};
+
+static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!");
+} // namespace
+
+template <typename OutT, typename InT> static OutT repr_cast(const InT &value) {
+ OutT result;
+ ::memcpy(&result, &value, sizeof(value));
+ return result;
+}
+
+PdbSymUid::PdbSymUid(const PdbCompilandId &cid) {
+ CompilandIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.modi = cid.modi;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::Compiland);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) {
+ CompilandSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.modi = csid.modi;
+ repr.offset = csid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::CompilandSym);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) {
+ GlobalSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.pub = gsid.is_public;
+ repr.offset = gsid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::GlobalSym);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) {
+ TypeSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.index = tsid.index.getIndex();
+ repr.ipi = tsid.is_ipi;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::Type);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) {
+ FieldListMemberIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.index = flmid.index.getIndex();
+ repr.offset = flmid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::FieldListMember);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUidKind PdbSymUid::kind() const {
+ GenericIdRepr generic = repr_cast<GenericIdRepr>(m_repr);
+ return static_cast<PdbSymUidKind>(generic.tag);
+}
+
+PdbCompilandId PdbSymUid::asCompiland() const {
+ assert(kind() == PdbSymUidKind::Compiland);
+ auto repr = repr_cast<CompilandIdRepr>(m_repr);
+ PdbCompilandId result;
+ result.modi = repr.modi;
+ return result;
+}
+
+PdbCompilandSymId PdbSymUid::asCompilandSym() const {
+ assert(kind() == PdbSymUidKind::CompilandSym);
+ auto repr = repr_cast<CompilandSymIdRepr>(m_repr);
+ PdbCompilandSymId result;
+ result.modi = repr.modi;
+ result.offset = repr.offset;
+ return result;
+}
+
+PdbGlobalSymId PdbSymUid::asGlobalSym() const {
+ assert(kind() == PdbSymUidKind::GlobalSym ||
+ kind() == PdbSymUidKind::PublicSym);
+ auto repr = repr_cast<GlobalSymIdRepr>(m_repr);
+ PdbGlobalSymId result;
+ result.is_public = repr.pub;
+ result.offset = repr.offset;
+ return result;
+}
+
+PdbTypeSymId PdbSymUid::asTypeSym() const {
+ assert(kind() == PdbSymUidKind::Type);
+ auto repr = repr_cast<TypeSymIdRepr>(m_repr);
+ PdbTypeSymId result;
+ result.index.setIndex(repr.index);
+ result.is_ipi = repr.ipi;
+ return result;
+}
+
+PdbFieldListMemberId PdbSymUid::asFieldListMember() const {
+ assert(kind() == PdbSymUidKind::FieldListMember);
+ auto repr = repr_cast<FieldListMemberIdRepr>(m_repr);
+ PdbFieldListMemberId result;
+ result.index.setIndex(repr.index);
+ result.offset = repr.offset;
+ return result;
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
new file mode 100644
index 000000000000..1166bee4e327
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
@@ -0,0 +1,126 @@
+//===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// A unique identification scheme for Pdb records.
+// The scheme is to partition a 64-bit integer into an 8-bit tag field, which
+// will contain some value from the PDB_SymType enumeration. The format of the
+// other 48-bits depend on the tag, but must be sufficient to locate the
+// corresponding entry in the underlying PDB file quickly. For example, for
+// a compile unit, we use 2 bytes to represent the index, which allows fast
+// access to the compile unit's information.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
+#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Support/Compiler.h"
+
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+namespace npdb {
+
+enum class PdbSymUidKind : uint8_t {
+ Compiland,
+ CompilandSym,
+ PublicSym,
+ GlobalSym,
+ Type,
+ FieldListMember
+};
+
+struct PdbCompilandId {
+ // 0-based index of module in PDB
+ uint16_t modi;
+};
+
+struct PdbCompilandSymId {
+ PdbCompilandSymId() = default;
+ PdbCompilandSymId(uint16_t modi, uint32_t offset)
+ : modi(modi), offset(offset) {}
+ // 0-based index of module in PDB
+ uint16_t modi = 0;
+
+ // Offset of symbol's record in module stream. This is
+ // offset by 4 from the CVSymbolArray's notion of offset
+ // due to the debug magic at the beginning of the stream.
+ uint32_t offset = 0;
+};
+
+struct PdbGlobalSymId {
+ PdbGlobalSymId() = default;
+ PdbGlobalSymId(uint32_t offset, bool is_public)
+ : offset(offset), is_public(is_public) {}
+
+ // Offset of symbol's record in globals or publics stream.
+ uint32_t offset = 0;
+
+ // True if this symbol is in the public stream, false if it's in the globals
+ // stream.
+ bool is_public = false;
+};
+
+struct PdbTypeSymId {
+ PdbTypeSymId() = default;
+ PdbTypeSymId(llvm::codeview::TypeIndex index, bool is_ipi = false)
+ : index(index), is_ipi(is_ipi) {}
+
+ // The index of the of the type in the TPI or IPI stream.
+ llvm::codeview::TypeIndex index;
+
+ // True if this symbol comes from the IPI stream, false if it's from the TPI
+ // stream.
+ bool is_ipi = false;
+};
+
+struct PdbFieldListMemberId {
+ // The TypeIndex of the LF_FIELDLIST record.
+ llvm::codeview::TypeIndex index;
+
+ // The offset from the beginning of the LF_FIELDLIST record to this record.
+ uint16_t offset = 0;
+};
+
+class PdbSymUid {
+ uint64_t m_repr = 0;
+
+public:
+ PdbSymUid() = default;
+ PdbSymUid(uint64_t repr) : m_repr(repr) {}
+ PdbSymUid(const PdbCompilandId &cid);
+ PdbSymUid(const PdbCompilandSymId &csid);
+ PdbSymUid(const PdbGlobalSymId &gsid);
+ PdbSymUid(const PdbTypeSymId &tsid);
+ PdbSymUid(const PdbFieldListMemberId &flmid);
+
+ uint64_t toOpaqueId() const { return m_repr; }
+
+ PdbSymUidKind kind() const;
+
+ PdbCompilandId asCompiland() const;
+ PdbCompilandSymId asCompilandSym() const;
+ PdbGlobalSymId asGlobalSym() const;
+ PdbTypeSymId asTypeSym() const;
+ PdbFieldListMemberId asFieldListMember() const;
+};
+
+template <typename T> uint64_t toOpaqueUid(const T &cid) {
+ return PdbSymUid(cid).toOpaqueId();
+}
+
+struct SymbolAndUid {
+ llvm::codeview::CVSymbol sym;
+ PdbSymUid uid;
+};
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
new file mode 100644
index 000000000000..317725dd250e
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp
@@ -0,0 +1,750 @@
+//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PdbUtil.h"
+
+#include "DWARFLocationExpression.h"
+#include "PdbIndex.h"
+#include "PdbSymUid.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-enumerations.h"
+
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+static Variable::RangeList
+MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
+ llvm::ArrayRef<LocalVariableAddrGap> gaps) {
+ lldb::addr_t start =
+ index.MakeVirtualAddress(range.ISectStart, range.OffsetStart);
+ lldb::addr_t end = start + range.Range;
+
+ Variable::RangeList result;
+ while (!gaps.empty()) {
+ const LocalVariableAddrGap &gap = gaps.front();
+
+ lldb::addr_t size = gap.GapStartOffset - start;
+ result.Append(start, size);
+ start += gap.Range;
+ gaps = gaps.drop_front();
+ }
+
+ result.Append(start, end);
+ return result;
+}
+
+CVTagRecord CVTagRecord::create(CVType type) {
+ assert(IsTagRecord(type) && "type is not a tag record!");
+ switch (type.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE: {
+ ClassRecord cr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr));
+ return CVTagRecord(std::move(cr));
+ }
+ case LF_UNION: {
+ UnionRecord ur;
+ llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur));
+ return CVTagRecord(std::move(ur));
+ }
+ case LF_ENUM: {
+ EnumRecord er;
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er));
+ return CVTagRecord(std::move(er));
+ }
+ default:
+ llvm_unreachable("Unreachable!");
+ }
+}
+
+CVTagRecord::CVTagRecord(ClassRecord &&c)
+ : cvclass(std::move(c)),
+ m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {}
+CVTagRecord::CVTagRecord(UnionRecord &&u)
+ : cvunion(std::move(u)), m_kind(Union) {}
+CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {}
+
+PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) {
+ switch (kind) {
+ case S_COMPILE3:
+ case S_OBJNAME:
+ return PDB_SymType::CompilandDetails;
+ case S_ENVBLOCK:
+ return PDB_SymType::CompilandEnv;
+ case S_THUNK32:
+ case S_TRAMPOLINE:
+ return PDB_SymType::Thunk;
+ case S_COFFGROUP:
+ return PDB_SymType::CoffGroup;
+ case S_EXPORT:
+ return PDB_SymType::Export;
+ case S_LPROC32:
+ case S_GPROC32:
+ case S_LPROC32_DPC:
+ return PDB_SymType::Function;
+ case S_PUB32:
+ return PDB_SymType::PublicSymbol;
+ case S_INLINESITE:
+ return PDB_SymType::InlineSite;
+ case S_LOCAL:
+ case S_BPREL32:
+ case S_REGREL32:
+ case S_MANCONSTANT:
+ case S_CONSTANT:
+ case S_LDATA32:
+ case S_GDATA32:
+ case S_LMANDATA:
+ case S_GMANDATA:
+ case S_LTHREAD32:
+ case S_GTHREAD32:
+ return PDB_SymType::Data;
+ case S_BLOCK32:
+ return PDB_SymType::Block;
+ case S_LABEL32:
+ return PDB_SymType::Label;
+ case S_CALLSITEINFO:
+ return PDB_SymType::CallSite;
+ case S_HEAPALLOCSITE:
+ return PDB_SymType::HeapAllocationSite;
+ case S_CALLEES:
+ return PDB_SymType::Callee;
+ case S_CALLERS:
+ return PDB_SymType::Caller;
+ default:
+ lldbassert(false && "Invalid symbol record kind!");
+ }
+ return PDB_SymType::None;
+}
+
+PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) {
+ switch (kind) {
+ case LF_ARRAY:
+ return PDB_SymType::ArrayType;
+ case LF_ARGLIST:
+ return PDB_SymType::FunctionSig;
+ case LF_BCLASS:
+ return PDB_SymType::BaseClass;
+ case LF_BINTERFACE:
+ return PDB_SymType::BaseInterface;
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ case LF_UNION:
+ return PDB_SymType::UDT;
+ case LF_POINTER:
+ return PDB_SymType::PointerType;
+ case LF_ENUM:
+ return PDB_SymType::Enum;
+ case LF_PROCEDURE:
+ return PDB_SymType::FunctionSig;
+ case LF_BITFIELD:
+ return PDB_SymType::BuiltinType;
+ default:
+ lldbassert(false && "Invalid type record kind!");
+ }
+ return PDB_SymType::None;
+}
+
+bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) {
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ case S_GPROC32_ID:
+ case S_LPROC32_ID:
+ case S_LPROC32_DPC:
+ case S_LPROC32_DPC_ID:
+ case S_THUNK32:
+ case S_TRAMPOLINE:
+ case S_COFFGROUP:
+ case S_BLOCK32:
+ case S_LABEL32:
+ case S_CALLSITEINFO:
+ case S_HEAPALLOCSITE:
+ case S_LDATA32:
+ case S_GDATA32:
+ case S_LMANDATA:
+ case S_GMANDATA:
+ case S_LTHREAD32:
+ case S_GTHREAD32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) {
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ case S_GPROC32_ID:
+ case S_LPROC32_ID:
+ case S_LPROC32_DPC:
+ case S_LPROC32_DPC_ID:
+ case S_THUNK32:
+ case S_TRAMPOLINE:
+ case S_COFFGROUP:
+ case S_BLOCK32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
+ RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
+ return record;
+}
+
+template <typename RecordT>
+static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) {
+ RecordT record = createRecord<RecordT>(sym);
+ return {record.Segment, record.CodeOffset};
+}
+
+template <>
+SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) {
+ TrampolineSym record = createRecord<TrampolineSym>(sym);
+ return {record.ThunkSection, record.ThunkOffset};
+}
+
+template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) {
+ Thunk32Sym record = createRecord<Thunk32Sym>(sym);
+ return {record.Segment, record.Offset};
+}
+
+template <>
+SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) {
+ CoffGroupSym record = createRecord<CoffGroupSym>(sym);
+ return {record.Segment, record.Offset};
+}
+
+template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) {
+ DataSym record = createRecord<DataSym>(sym);
+ return {record.Segment, record.DataOffset};
+}
+
+template <>
+SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) {
+ ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym);
+ return {record.Segment, record.DataOffset};
+}
+
+SegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) {
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ case S_GPROC32_ID:
+ case S_LPROC32_ID:
+ case S_LPROC32_DPC:
+ case S_LPROC32_DPC_ID:
+ return ::GetSegmentAndOffset<ProcSym>(sym);
+ case S_THUNK32:
+ return ::GetSegmentAndOffset<Thunk32Sym>(sym);
+ break;
+ case S_TRAMPOLINE:
+ return ::GetSegmentAndOffset<TrampolineSym>(sym);
+ break;
+ case S_COFFGROUP:
+ return ::GetSegmentAndOffset<CoffGroupSym>(sym);
+ break;
+ case S_BLOCK32:
+ return ::GetSegmentAndOffset<BlockSym>(sym);
+ break;
+ case S_LABEL32:
+ return ::GetSegmentAndOffset<LabelSym>(sym);
+ break;
+ case S_CALLSITEINFO:
+ return ::GetSegmentAndOffset<CallSiteInfoSym>(sym);
+ break;
+ case S_HEAPALLOCSITE:
+ return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym);
+ break;
+ case S_LDATA32:
+ case S_GDATA32:
+ case S_LMANDATA:
+ case S_GMANDATA:
+ return ::GetSegmentAndOffset<DataSym>(sym);
+ break;
+ case S_LTHREAD32:
+ case S_GTHREAD32:
+ return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym);
+ break;
+ default:
+ lldbassert(false && "Record does not have a segment/offset!");
+ }
+ return {0, 0};
+}
+
+template <typename RecordT>
+SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) {
+ RecordT record = createRecord<RecordT>(sym);
+ return {record.Segment, record.CodeOffset, record.CodeSize};
+}
+
+template <>
+SegmentOffsetLength
+GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) {
+ TrampolineSym record = createRecord<TrampolineSym>(sym);
+ return {record.ThunkSection, record.ThunkOffset, record.Size};
+}
+
+template <>
+SegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) {
+ Thunk32Sym record = createRecord<Thunk32Sym>(sym);
+ return SegmentOffsetLength{record.Segment, record.Offset, record.Length};
+}
+
+template <>
+SegmentOffsetLength
+GetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) {
+ CoffGroupSym record = createRecord<CoffGroupSym>(sym);
+ return SegmentOffsetLength{record.Segment, record.Offset, record.Size};
+}
+
+SegmentOffsetLength
+lldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) {
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32:
+ case S_GPROC32_ID:
+ case S_LPROC32_ID:
+ case S_LPROC32_DPC:
+ case S_LPROC32_DPC_ID:
+ return ::GetSegmentOffsetAndLength<ProcSym>(sym);
+ case S_THUNK32:
+ return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym);
+ break;
+ case S_TRAMPOLINE:
+ return ::GetSegmentOffsetAndLength<TrampolineSym>(sym);
+ break;
+ case S_COFFGROUP:
+ return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym);
+ break;
+ case S_BLOCK32:
+ return ::GetSegmentOffsetAndLength<BlockSym>(sym);
+ break;
+ default:
+ lldbassert(false && "Record does not have a segment/offset/length triple!");
+ }
+ return {0, 0, 0};
+}
+
+bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) {
+ ClassRecord cr;
+ UnionRecord ur;
+ EnumRecord er;
+ switch (cvt.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
+ return cr.isForwardRef();
+ case LF_UNION:
+ llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
+ return ur.isForwardRef();
+ case LF_ENUM:
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
+ return er.isForwardRef();
+ default:
+ return false;
+ }
+}
+
+bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) {
+ switch (cvt.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_UNION:
+ case LF_ENUM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) {
+ switch (cvt.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_UNION:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id,
+ TpiStream &tpi) {
+ if (id.is_ipi || id.index.isSimple())
+ return false;
+ return IsForwardRefUdt(tpi.getType(id.index));
+}
+
+bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) {
+ if (id.is_ipi || id.index.isSimple())
+ return false;
+ return IsTagRecord(tpi.getType(id.index));
+}
+
+lldb::AccessType
+lldb_private::npdb::TranslateMemberAccess(MemberAccess access) {
+ switch (access) {
+ case MemberAccess::Private:
+ return lldb::eAccessPrivate;
+ case MemberAccess::Protected:
+ return lldb::eAccessProtected;
+ case MemberAccess::Public:
+ return lldb::eAccessPublic;
+ case MemberAccess::None:
+ return lldb::eAccessNone;
+ }
+ llvm_unreachable("unreachable");
+}
+
+TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) {
+ switch (cvt.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE: {
+ ClassRecord cr;
+ cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
+ return cr.FieldList;
+ }
+ case LF_UNION: {
+ UnionRecord ur;
+ cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
+ return ur.FieldList;
+ }
+ case LF_ENUM: {
+ EnumRecord er;
+ cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
+ return er.FieldList;
+ }
+ default:
+ llvm_unreachable("Unreachable!");
+ }
+}
+
+TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) {
+ lldbassert(modifier.kind() == LF_MODIFIER);
+ ModifierRecord mr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr));
+ return mr.ModifiedType;
+}
+
+llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
+ return MSVCUndecoratedNameParser::DropScope(name);
+}
+
+VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) {
+ VariableInfo result;
+
+ if (sym.kind() == S_REGREL32) {
+ RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
+ result.type = reg.Type;
+ result.name = reg.Name;
+ return result;
+ }
+
+ if (sym.kind() == S_REGISTER) {
+ RegisterSym reg(SymbolRecordKind::RegisterSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
+ result.type = reg.Index;
+ result.name = reg.Name;
+ return result;
+ }
+
+ if (sym.kind() == S_LOCAL) {
+ LocalSym local(SymbolRecordKind::LocalSym);
+ cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
+ result.type = local.Type;
+ result.name = local.Name;
+ return result;
+ }
+
+ if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) {
+ DataSym data(SymbolRecordKind::DataSym);
+ cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data));
+ result.type = data.Type;
+ result.name = data.Name;
+ return result;
+ }
+
+ if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) {
+ ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym);
+ cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data));
+ result.type = data.Type;
+ result.name = data.Name;
+ return result;
+ }
+
+ if (sym.kind() == S_CONSTANT) {
+ ConstantSym constant(SymbolRecordKind::ConstantSym);
+ cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant));
+ result.type = constant.Type;
+ result.name = constant.Name;
+ return result;
+ }
+
+ lldbassert(false && "Invalid variable record kind!");
+ return {};
+}
+
+VariableInfo lldb_private::npdb::GetVariableLocationInfo(
+ PdbIndex &index, PdbCompilandSymId var_id, lldb::ModuleSP module) {
+
+ CVSymbol sym = index.ReadSymbolRecord(var_id);
+
+ VariableInfo result = GetVariableNameInfo(sym);
+
+ if (sym.kind() == S_REGREL32) {
+ RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
+ result.location =
+ MakeRegRelLocationExpression(reg.Register, reg.Offset, module);
+ result.ranges.emplace();
+ return result;
+ }
+
+ if (sym.kind() == S_REGISTER) {
+ RegisterSym reg(SymbolRecordKind::RegisterSym);
+ cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
+ result.location = MakeEnregisteredLocationExpression(reg.Register, module);
+ result.ranges.emplace();
+ return result;
+ }
+
+ if (sym.kind() == S_LOCAL) {
+ LocalSym local(SymbolRecordKind::LocalSym);
+ cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
+
+ PdbCompilandSymId loc_specifier_id(var_id.modi,
+ var_id.offset + sym.RecordData.size());
+ CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
+ if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) {
+ DefRangeFramePointerRelSym loc(
+ SymbolRecordKind::DefRangeFramePointerRelSym);
+ cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
+ loc_specifier_cvs, loc));
+ // FIXME: The register needs to come from the S_FRAMEPROC symbol.
+ result.location =
+ MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module);
+ result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
+ } else {
+ // FIXME: Handle other kinds
+ }
+ return result;
+ }
+ llvm_unreachable("Symbol is not a local variable!");
+ return result;
+}
+
+lldb::BasicType
+lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
+ switch (kind) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Boolean8:
+ return lldb::eBasicTypeBool;
+ case SimpleTypeKind::Byte:
+ case SimpleTypeKind::UnsignedCharacter:
+ return lldb::eBasicTypeUnsignedChar;
+ case SimpleTypeKind::NarrowCharacter:
+ return lldb::eBasicTypeChar;
+ case SimpleTypeKind::SignedCharacter:
+ case SimpleTypeKind::SByte:
+ return lldb::eBasicTypeSignedChar;
+ case SimpleTypeKind::Character16:
+ return lldb::eBasicTypeChar16;
+ case SimpleTypeKind::Character32:
+ return lldb::eBasicTypeChar32;
+ case SimpleTypeKind::Complex80:
+ return lldb::eBasicTypeLongDoubleComplex;
+ case SimpleTypeKind::Complex64:
+ return lldb::eBasicTypeDoubleComplex;
+ case SimpleTypeKind::Complex32:
+ return lldb::eBasicTypeFloatComplex;
+ case SimpleTypeKind::Float128:
+ case SimpleTypeKind::Float80:
+ return lldb::eBasicTypeLongDouble;
+ case SimpleTypeKind::Float64:
+ return lldb::eBasicTypeDouble;
+ case SimpleTypeKind::Float32:
+ return lldb::eBasicTypeFloat;
+ case SimpleTypeKind::Float16:
+ return lldb::eBasicTypeHalf;
+ case SimpleTypeKind::Int128:
+ return lldb::eBasicTypeInt128;
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return lldb::eBasicTypeLongLong;
+ case SimpleTypeKind::Int32:
+ return lldb::eBasicTypeInt;
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ return lldb::eBasicTypeShort;
+ case SimpleTypeKind::UInt128:
+ return lldb::eBasicTypeUnsignedInt128;
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ return lldb::eBasicTypeUnsignedLongLong;
+ case SimpleTypeKind::HResult:
+ case SimpleTypeKind::UInt32:
+ return lldb::eBasicTypeUnsignedInt;
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ return lldb::eBasicTypeUnsignedShort;
+ case SimpleTypeKind::Int32Long:
+ return lldb::eBasicTypeLong;
+ case SimpleTypeKind::UInt32Long:
+ return lldb::eBasicTypeUnsignedLong;
+ case SimpleTypeKind::Void:
+ return lldb::eBasicTypeVoid;
+ case SimpleTypeKind::WideCharacter:
+ return lldb::eBasicTypeWChar;
+ default:
+ return lldb::eBasicTypeInvalid;
+ }
+}
+
+size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
+ switch (kind) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Int128:
+ case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::Float128:
+ return 16;
+ case SimpleTypeKind::Complex80:
+ case SimpleTypeKind::Float80:
+ return 10;
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Complex64:
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ case SimpleTypeKind::Float64:
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return 8;
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Character32:
+ case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Int32:
+ case SimpleTypeKind::Int32Long:
+ case SimpleTypeKind::UInt32Long:
+ case SimpleTypeKind::HResult:
+ case SimpleTypeKind::UInt32:
+ return 4;
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Character16:
+ case SimpleTypeKind::Float16:
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ case SimpleTypeKind::WideCharacter:
+ return 2;
+ case SimpleTypeKind::Boolean8:
+ case SimpleTypeKind::Byte:
+ case SimpleTypeKind::UnsignedCharacter:
+ case SimpleTypeKind::NarrowCharacter:
+ case SimpleTypeKind::SignedCharacter:
+ case SimpleTypeKind::SByte:
+ return 1;
+ case SimpleTypeKind::Void:
+ default:
+ return 0;
+ }
+}
+
+PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id,
+ TpiStream &tpi) {
+ if (id.index.isSimple())
+ return id;
+
+ CVType cvt = tpi.getType(id.index);
+
+ // Only tag records have a best and a worst record.
+ if (!IsTagRecord(cvt))
+ return id;
+
+ // Tag records that are not forward decls are full decls, hence they are the
+ // best.
+ if (!IsForwardRefUdt(cvt))
+ return id;
+
+ return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index));
+}
+
+template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) {
+ RecordType record;
+ llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record));
+ return record.getSize();
+}
+
+size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id,
+ llvm::pdb::TpiStream &tpi) {
+ if (id.index.isSimple()) {
+ switch (id.index.getSimpleMode()) {
+ case SimpleTypeMode::Direct:
+ return GetTypeSizeForSimpleKind(id.index.getSimpleKind());
+ case SimpleTypeMode::NearPointer32:
+ case SimpleTypeMode::FarPointer32:
+ return 4;
+ case SimpleTypeMode::NearPointer64:
+ return 8;
+ case SimpleTypeMode::NearPointer128:
+ return 16;
+ default:
+ break;
+ }
+ return 0;
+ }
+
+ TypeIndex index = id.index;
+ if (IsForwardRefUdt(index, tpi))
+ index = llvm::cantFail(tpi.findFullDeclForForwardRef(index));
+
+ CVType cvt = tpi.getType(index);
+ switch (cvt.kind()) {
+ case LF_MODIFIER:
+ return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi);
+ case LF_ENUM: {
+ EnumRecord record;
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record));
+ return GetSizeOfType({record.UnderlyingType}, tpi);
+ }
+ case LF_POINTER:
+ return GetSizeOfTypeInternal<PointerRecord>(cvt);
+ case LF_ARRAY:
+ return GetSizeOfTypeInternal<ArrayRecord>(cvt);
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ return GetSizeOfTypeInternal<ClassRecord>(cvt);
+ case LF_UNION:
+ return GetSizeOfTypeInternal<UnionRecord>(cvt);
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
new file mode 100644
index 000000000000..570c300b6a2b
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbUtil.h
@@ -0,0 +1,159 @@
+//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
+#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
+
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/Variable.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include "PdbSymUid.h"
+
+#include <tuple>
+#include <utility>
+
+namespace llvm {
+namespace pdb {
+class TpiStream;
+}
+} // namespace llvm
+
+namespace lldb_private {
+namespace npdb {
+
+class PdbIndex;
+
+struct CVTagRecord {
+ enum Kind { Class, Struct, Union, Enum };
+
+ static CVTagRecord create(llvm::codeview::CVType type);
+
+ Kind kind() const { return m_kind; }
+
+ const llvm::codeview::TagRecord &asTag() const {
+ if (m_kind == Struct || m_kind == Class)
+ return cvclass;
+ if (m_kind == Enum)
+ return cvenum;
+ return cvunion;
+ }
+
+ const llvm::codeview::ClassRecord &asClass() const {
+ assert(m_kind == Struct || m_kind == Class);
+ return cvclass;
+ }
+
+ const llvm::codeview::EnumRecord &asEnum() const {
+ assert(m_kind == Enum);
+ return cvenum;
+ }
+
+ const llvm::codeview::UnionRecord &asUnion() const {
+ assert(m_kind == Union);
+ return cvunion;
+ }
+
+ llvm::StringRef name() const {
+ if (m_kind == Struct || m_kind == Union)
+ return cvclass.Name;
+ if (m_kind == Enum)
+ return cvenum.Name;
+ return cvunion.Name;
+ }
+
+private:
+ CVTagRecord(llvm::codeview::ClassRecord &&c);
+ CVTagRecord(llvm::codeview::UnionRecord &&u);
+ CVTagRecord(llvm::codeview::EnumRecord &&e);
+ union {
+ llvm::codeview::ClassRecord cvclass;
+ llvm::codeview::EnumRecord cvenum;
+ llvm::codeview::UnionRecord cvunion;
+ };
+ Kind m_kind;
+};
+
+struct SegmentOffset {
+ SegmentOffset() = default;
+ SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
+ uint16_t segment = 0;
+ uint32_t offset = 0;
+};
+
+struct SegmentOffsetLength {
+ SegmentOffsetLength() = default;
+ SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l)
+ : so(s, o), length(l) {}
+ SegmentOffset so;
+ uint32_t length = 0;
+};
+
+struct VariableInfo {
+ llvm::StringRef name;
+ llvm::codeview::TypeIndex type;
+ llvm::Optional<DWARFExpression> location;
+ llvm::Optional<Variable::RangeList> ranges;
+};
+
+llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
+llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
+
+bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
+bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
+
+SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
+SegmentOffsetLength
+GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
+
+template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
+ return true;
+}
+
+inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
+ // S_PROCREF symbols have 1-based module indices.
+ return sym.Module > 0;
+}
+
+bool IsForwardRefUdt(llvm::codeview::CVType cvt);
+bool IsTagRecord(llvm::codeview::CVType cvt);
+bool IsClassStructUnion(llvm::codeview::CVType cvt);
+
+bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
+bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
+
+lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
+llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
+llvm::codeview::TypeIndex
+LookThroughModifierRecord(llvm::codeview::CVType modifier);
+
+llvm::StringRef DropNameScope(llvm::StringRef name);
+
+VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
+VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id,
+ lldb::ModuleSP module);
+
+size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
+lldb::BasicType
+GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
+
+PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
+
+size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
new file mode 100644
index 000000000000..7e97e2b37724
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -0,0 +1,1571 @@
+//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileNativePDB.h"
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/StreamBuffer.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/Variable.h"
+#include "lldb/Symbol/VariableList.h"
+
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Demangle/MicrosoftDemangle.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include "DWARFLocationExpression.h"
+#include "PdbAstBuilder.h"
+#include "PdbSymUid.h"
+#include "PdbUtil.h"
+#include "UdtRecordCompleter.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace npdb;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
+ switch (lang) {
+ case PDB_Lang::Cpp:
+ return lldb::LanguageType::eLanguageTypeC_plus_plus;
+ case PDB_Lang::C:
+ return lldb::LanguageType::eLanguageTypeC;
+ default:
+ return lldb::LanguageType::eLanguageTypeUnknown;
+ }
+}
+
+static std::unique_ptr<PDBFile> loadPDBFile(std::string PdbPath,
+ llvm::BumpPtrAllocator &Allocator) {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ErrorOrBuffer =
+ llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
+ /*RequiresNullTerminator=*/false);
+ if (!ErrorOrBuffer)
+ return nullptr;
+ std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
+
+ llvm::StringRef Path = Buffer->getBufferIdentifier();
+ auto Stream = llvm::make_unique<llvm::MemoryBufferByteStream>(
+ std::move(Buffer), llvm::support::little);
+
+ auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), Allocator);
+ if (auto EC = File->parseFileHeaders()) {
+ llvm::consumeError(std::move(EC));
+ return nullptr;
+ }
+ if (auto EC = File->parseStreamData()) {
+ llvm::consumeError(std::move(EC));
+ return nullptr;
+ }
+
+ return File;
+}
+
+static std::unique_ptr<PDBFile>
+loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
+ // Try to find a matching PDB for an EXE.
+ using namespace llvm::object;
+ auto expected_binary = createBinary(exe_path);
+
+ // If the file isn't a PE/COFF executable, fail.
+ if (!expected_binary) {
+ llvm::consumeError(expected_binary.takeError());
+ return nullptr;
+ }
+ OwningBinary<Binary> binary = std::move(*expected_binary);
+
+ auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
+ if (!obj)
+ return nullptr;
+ const llvm::codeview::DebugInfo *pdb_info = nullptr;
+
+ // If it doesn't have a debug directory, fail.
+ llvm::StringRef pdb_file;
+ auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file);
+ if (ec)
+ return nullptr;
+
+ // if the file doesn't exist, is not a pdb, or doesn't have a matching guid,
+ // fail.
+ llvm::file_magic magic;
+ ec = llvm::identify_magic(pdb_file, magic);
+ if (ec || magic != llvm::file_magic::pdb)
+ return nullptr;
+ std::unique_ptr<PDBFile> pdb = loadPDBFile(pdb_file, allocator);
+ if (!pdb)
+ return nullptr;
+
+ auto expected_info = pdb->getPDBInfoStream();
+ if (!expected_info) {
+ llvm::consumeError(expected_info.takeError());
+ return nullptr;
+ }
+ llvm::codeview::GUID guid;
+ memcpy(&guid, pdb_info->PDB70.Signature, 16);
+
+ if (expected_info->getGuid() != guid)
+ return nullptr;
+ return pdb;
+}
+
+static bool IsFunctionPrologue(const CompilandIndexItem &cci,
+ lldb::addr_t addr) {
+ // FIXME: Implement this.
+ return false;
+}
+
+static bool IsFunctionEpilogue(const CompilandIndexItem &cci,
+ lldb::addr_t addr) {
+ // FIXME: Implement this.
+ return false;
+}
+
+static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
+ switch (kind) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Boolean8:
+ return "bool";
+ case SimpleTypeKind::Byte:
+ case SimpleTypeKind::UnsignedCharacter:
+ return "unsigned char";
+ case SimpleTypeKind::NarrowCharacter:
+ return "char";
+ case SimpleTypeKind::SignedCharacter:
+ case SimpleTypeKind::SByte:
+ return "signed char";
+ case SimpleTypeKind::Character16:
+ return "char16_t";
+ case SimpleTypeKind::Character32:
+ return "char32_t";
+ case SimpleTypeKind::Complex80:
+ case SimpleTypeKind::Complex64:
+ case SimpleTypeKind::Complex32:
+ return "complex";
+ case SimpleTypeKind::Float128:
+ case SimpleTypeKind::Float80:
+ return "long double";
+ case SimpleTypeKind::Float64:
+ return "double";
+ case SimpleTypeKind::Float32:
+ return "float";
+ case SimpleTypeKind::Float16:
+ return "single";
+ case SimpleTypeKind::Int128:
+ return "__int128";
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return "int64_t";
+ case SimpleTypeKind::Int32:
+ return "int";
+ case SimpleTypeKind::Int16:
+ return "short";
+ case SimpleTypeKind::UInt128:
+ return "unsigned __int128";
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ return "uint64_t";
+ case SimpleTypeKind::HResult:
+ return "HRESULT";
+ case SimpleTypeKind::UInt32:
+ return "unsigned";
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ return "unsigned short";
+ case SimpleTypeKind::Int32Long:
+ return "long";
+ case SimpleTypeKind::UInt32Long:
+ return "unsigned long";
+ case SimpleTypeKind::Void:
+ return "void";
+ case SimpleTypeKind::WideCharacter:
+ return "wchar_t";
+ default:
+ return "";
+ }
+}
+
+static bool IsClassRecord(TypeLeafKind kind) {
+ switch (kind) {
+ case LF_STRUCTURE:
+ case LF_CLASS:
+ case LF_INTERFACE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void SymbolFileNativePDB::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+}
+
+void SymbolFileNativePDB::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {}
+
+ConstString SymbolFileNativePDB::GetPluginNameStatic() {
+ static ConstString g_name("native-pdb");
+ return g_name;
+}
+
+const char *SymbolFileNativePDB::GetPluginDescriptionStatic() {
+ return "Microsoft PDB debug symbol cross-platform file reader.";
+}
+
+SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) {
+ return new SymbolFileNativePDB(obj_file);
+}
+
+SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file)
+ : SymbolFile(object_file) {}
+
+SymbolFileNativePDB::~SymbolFileNativePDB() {}
+
+uint32_t SymbolFileNativePDB::CalculateAbilities() {
+ uint32_t abilities = 0;
+ if (!m_obj_file)
+ return 0;
+
+ if (!m_index) {
+ // Lazily load and match the PDB file, but only do this once.
+ std::unique_ptr<PDBFile> file_up =
+ loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator);
+
+ if (!file_up) {
+ auto module_sp = m_obj_file->GetModule();
+ if (!module_sp)
+ return 0;
+ // See if any symbol file is specified through `--symfile` option.
+ FileSpec symfile = module_sp->GetSymbolFileFileSpec();
+ if (!symfile)
+ return 0;
+ file_up = loadPDBFile(symfile.GetPath(), m_allocator);
+ }
+
+ if (!file_up)
+ return 0;
+
+ auto expected_index = PdbIndex::create(std::move(file_up));
+ if (!expected_index) {
+ llvm::consumeError(expected_index.takeError());
+ return 0;
+ }
+ m_index = std::move(*expected_index);
+ }
+ if (!m_index)
+ return 0;
+
+ // We don't especially have to be precise here. We only distinguish between
+ // stripped and not stripped.
+ abilities = kAllAbilities;
+
+ if (m_index->dbi().isStripped())
+ abilities &= ~(Blocks | LocalVariables);
+ return abilities;
+}
+
+void SymbolFileNativePDB::InitializeObject() {
+ m_obj_load_address = m_obj_file->GetFileOffset();
+ m_index->SetLoadAddress(m_obj_load_address);
+ m_index->ParseSectionContribs();
+
+ TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage(
+ lldb::eLanguageTypeC_plus_plus);
+ if (ts)
+ ts->SetSymbolFile(this);
+
+ m_ast = llvm::make_unique<PdbAstBuilder>(*m_obj_file, *m_index);
+}
+
+uint32_t SymbolFileNativePDB::GetNumCompileUnits() {
+ const DbiModuleList &modules = m_index->dbi().modules();
+ uint32_t count = modules.getModuleCount();
+ if (count == 0)
+ return count;
+
+ // The linker can inject an additional "dummy" compilation unit into the
+ // PDB. Ignore this special compile unit for our purposes, if it is there.
+ // It is always the last one.
+ DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1);
+ if (last.getModuleName() == "* Linker *")
+ --count;
+ return count;
+}
+
+Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
+ CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
+
+ if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) {
+ // This is a function. It must be global. Creating the Function entry for
+ // it automatically creates a block for it.
+ CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
+ return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false);
+ }
+
+ lldbassert(sym.kind() == S_BLOCK32);
+
+ // This is a block. Its parent is either a function or another block. In
+ // either case, its parent can be viewed as a block (e.g. a function contains
+ // 1 big block. So just get the parent block and add this block to it.
+ BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
+ lldbassert(block.Parent != 0);
+ PdbCompilandSymId parent_id(block_id.modi, block.Parent);
+ Block &parent_block = GetOrCreateBlock(parent_id);
+ lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
+ BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
+ parent_block.AddChild(child_block);
+
+ m_ast->GetOrCreateBlockDecl(block_id);
+
+ m_blocks.insert({opaque_block_uid, child_block});
+ return *child_block;
+}
+
+lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
+ CompileUnit &comp_unit) {
+ const CompilandIndexItem *cci =
+ m_index->compilands().GetCompiland(func_id.modi);
+ lldbassert(cci);
+ CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset);
+
+ lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32);
+ SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record);
+
+ auto file_vm_addr = m_index->MakeVirtualAddress(sol.so);
+ if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
+ return nullptr;
+
+ AddressRange func_range(file_vm_addr, sol.length,
+ comp_unit.GetModule()->GetSectionList());
+ if (!func_range.GetBaseAddress().IsValid())
+ return nullptr;
+
+ ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc));
+ if (proc.FunctionType == TypeIndex::None())
+ return nullptr;
+ TypeSP func_type = GetOrCreateType(proc.FunctionType);
+ if (!func_type)
+ return nullptr;
+
+ PdbTypeSymId sig_id(proc.FunctionType, false);
+ Mangled mangled(proc.Name);
+ FunctionSP func_sp = std::make_shared<Function>(
+ &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
+ func_type.get(), func_range);
+
+ comp_unit.AddFunction(func_sp);
+
+ m_ast->GetOrCreateFunctionDecl(func_id);
+
+ return func_sp;
+}
+
+CompUnitSP
+SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) {
+ lldb::LanguageType lang =
+ cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage())
+ : lldb::eLanguageTypeUnknown;
+
+ LazyBool optimized = eLazyBoolNo;
+ if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations())
+ optimized = eLazyBoolYes;
+
+ llvm::SmallString<64> source_file_name =
+ m_index->compilands().GetMainSourceFile(cci);
+ FileSpec fs(source_file_name);
+
+ CompUnitSP cu_sp =
+ std::make_shared<CompileUnit>(m_obj_file->GetModule(), nullptr, fs,
+ toOpaqueUid(cci.m_id), lang, optimized);
+
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+ cci.m_id.modi, cu_sp);
+ return cu_sp;
+}
+
+lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id,
+ const ModifierRecord &mr,
+ CompilerType ct) {
+ TpiStream &stream = m_index->tpi();
+
+ std::string name;
+ if (mr.ModifiedType.isSimple())
+ name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind());
+ else
+ name = computeTypeName(stream.typeCollection(), mr.ModifiedType);
+ Declaration decl;
+ lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType);
+
+ return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(name),
+ modified_type->GetByteSize(), nullptr,
+ LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
+ ct, Type::eResolveStateFull);
+}
+
+lldb::TypeSP
+SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id,
+ const llvm::codeview::PointerRecord &pr,
+ CompilerType ct) {
+ TypeSP pointee = GetOrCreateType(pr.ReferentType);
+ if (!pointee)
+ return nullptr;
+
+ if (pr.isPointerToMember()) {
+ MemberPointerInfo mpi = pr.getMemberInfo();
+ GetOrCreateType(mpi.ContainingType);
+ }
+
+ Declaration decl;
+ return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(),
+ pr.getSize(), nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, ct,
+ Type::eResolveStateFull);
+}
+
+lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti,
+ CompilerType ct) {
+ uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false));
+ if (ti == TypeIndex::NullptrT()) {
+ Declaration decl;
+ return std::make_shared<Type>(
+ uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull);
+ }
+
+ if (ti.getSimpleMode() != SimpleTypeMode::Direct) {
+ TypeSP direct_sp = GetOrCreateType(ti.makeDirect());
+ uint32_t pointer_size = 0;
+ switch (ti.getSimpleMode()) {
+ case SimpleTypeMode::FarPointer32:
+ case SimpleTypeMode::NearPointer32:
+ pointer_size = 4;
+ break;
+ case SimpleTypeMode::NearPointer64:
+ pointer_size = 8;
+ break;
+ default:
+ // 128-bit and 16-bit pointers unsupported.
+ return nullptr;
+ }
+ Declaration decl;
+ return std::make_shared<Type>(
+ uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull);
+ }
+
+ if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated)
+ return nullptr;
+
+ size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind());
+ llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind());
+
+ Declaration decl;
+ return std::make_shared<Type>(uid, this, ConstString(type_name), size,
+ nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID,
+ decl, ct, Type::eResolveStateFull);
+}
+
+static std::string GetUnqualifiedTypeName(const TagRecord &record) {
+ if (!record.hasUniqueName()) {
+ MSVCUndecoratedNameParser parser(record.Name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+ return specs.back().GetBaseName();
+ }
+
+ llvm::ms_demangle::Demangler demangler;
+ StringView sv(record.UniqueName.begin(), record.UniqueName.size());
+ llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv);
+ if (demangler.Error)
+ return record.Name;
+
+ llvm::ms_demangle::IdentifierNode *idn =
+ ttn->QualifiedName->getUnqualifiedIdentifier();
+ return idn->toString();
+}
+
+lldb::TypeSP
+SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id,
+ const TagRecord &record,
+ size_t size, CompilerType ct) {
+
+ std::string uname = GetUnqualifiedTypeName(record);
+
+ // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE.
+ Declaration decl;
+ return std::make_shared<Type>(toOpaqueUid(type_id), this, ConstString(uname),
+ size, nullptr, LLDB_INVALID_UID,
+ Type::eEncodingIsUID, decl, ct,
+ Type::eResolveStateForward);
+}
+
+lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
+ const ClassRecord &cr,
+ CompilerType ct) {
+ return CreateClassStructUnion(type_id, cr, cr.getSize(), ct);
+}
+
+lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
+ const UnionRecord &ur,
+ CompilerType ct) {
+ return CreateClassStructUnion(type_id, ur, ur.getSize(), ct);
+}
+
+lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id,
+ const EnumRecord &er,
+ CompilerType ct) {
+ std::string uname = GetUnqualifiedTypeName(er);
+
+ Declaration decl;
+ TypeSP underlying_type = GetOrCreateType(er.UnderlyingType);
+
+ return std::make_shared<lldb_private::Type>(
+ toOpaqueUid(type_id), this, ConstString(uname),
+ underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, ct,
+ lldb_private::Type::eResolveStateForward);
+}
+
+TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id,
+ const ArrayRecord &ar,
+ CompilerType ct) {
+ TypeSP element_type = GetOrCreateType(ar.ElementType);
+
+ Declaration decl;
+ TypeSP array_sp = std::make_shared<lldb_private::Type>(
+ toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr,
+ LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct,
+ lldb_private::Type::eResolveStateFull);
+ array_sp->SetEncodingType(element_type.get());
+ return array_sp;
+}
+
+TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id,
+ const ProcedureRecord &pr,
+ CompilerType ct) {
+ Declaration decl;
+ return std::make_shared<lldb_private::Type>(
+ toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, ct,
+ lldb_private::Type::eResolveStateFull);
+}
+
+TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) {
+ if (type_id.index.isSimple())
+ return CreateSimpleType(type_id.index, ct);
+
+ TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi();
+ CVType cvt = stream.getType(type_id.index);
+
+ if (cvt.kind() == LF_MODIFIER) {
+ ModifierRecord modifier;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier));
+ return CreateModifierType(type_id, modifier, ct);
+ }
+
+ if (cvt.kind() == LF_POINTER) {
+ PointerRecord pointer;
+ llvm::cantFail(
+ TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer));
+ return CreatePointerType(type_id, pointer, ct);
+ }
+
+ if (IsClassRecord(cvt.kind())) {
+ ClassRecord cr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr));
+ return CreateTagType(type_id, cr, ct);
+ }
+
+ if (cvt.kind() == LF_ENUM) {
+ EnumRecord er;
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
+ return CreateTagType(type_id, er, ct);
+ }
+
+ if (cvt.kind() == LF_UNION) {
+ UnionRecord ur;
+ llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur));
+ return CreateTagType(type_id, ur, ct);
+ }
+
+ if (cvt.kind() == LF_ARRAY) {
+ ArrayRecord ar;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar));
+ return CreateArrayType(type_id, ar, ct);
+ }
+
+ if (cvt.kind() == LF_PROCEDURE) {
+ ProcedureRecord pr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr));
+ return CreateProcedureType(type_id, pr, ct);
+ }
+
+ return nullptr;
+}
+
+TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {
+ // If they search for a UDT which is a forward ref, try and resolve the full
+ // decl and just map the forward ref uid to the full decl record.
+ llvm::Optional<PdbTypeSymId> full_decl_uid;
+ if (IsForwardRefUdt(type_id, m_index->tpi())) {
+ auto expected_full_ti =
+ m_index->tpi().findFullDeclForForwardRef(type_id.index);
+ if (!expected_full_ti)
+ llvm::consumeError(expected_full_ti.takeError());
+ else if (*expected_full_ti != type_id.index) {
+ full_decl_uid = PdbTypeSymId(*expected_full_ti, false);
+
+ // It's possible that a lookup would occur for the full decl causing it
+ // to be cached, then a second lookup would occur for the forward decl.
+ // We don't want to create a second full decl, so make sure the full
+ // decl hasn't already been cached.
+ auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid));
+ if (full_iter != m_types.end()) {
+ TypeSP result = full_iter->second;
+ // Map the forward decl to the TypeSP for the full decl so we can take
+ // the fast path next time.
+ m_types[toOpaqueUid(type_id)] = result;
+ return result;
+ }
+ }
+ }
+
+ PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id;
+
+ clang::QualType qt = m_ast->GetOrCreateType(best_decl_id);
+
+ TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt));
+ if (!result)
+ return nullptr;
+
+ uint64_t best_uid = toOpaqueUid(best_decl_id);
+ m_types[best_uid] = result;
+ // If we had both a forward decl and a full decl, make both point to the new
+ // type.
+ if (full_decl_uid)
+ m_types[toOpaqueUid(type_id)] = result;
+
+ return result;
+}
+
+TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
+ // We can't use try_emplace / overwrite here because the process of creating
+ // a type could create nested types, which could invalidate iterators. So
+ // we have to do a 2-phase lookup / insert.
+ auto iter = m_types.find(toOpaqueUid(type_id));
+ if (iter != m_types.end())
+ return iter->second;
+
+ TypeSP type = CreateAndCacheType(type_id);
+ if (type)
+ m_obj_file->GetModule()->GetTypeList()->Insert(type);
+ return type;
+}
+
+VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
+ CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
+ if (sym.kind() == S_CONSTANT)
+ return CreateConstantSymbol(var_id, sym);
+
+ lldb::ValueType scope = eValueTypeInvalid;
+ TypeIndex ti;
+ llvm::StringRef name;
+ lldb::addr_t addr = 0;
+ uint16_t section = 0;
+ uint32_t offset = 0;
+ bool is_external = false;
+ switch (sym.kind()) {
+ case S_GDATA32:
+ is_external = true;
+ LLVM_FALLTHROUGH;
+ case S_LDATA32: {
+ DataSym ds(sym.kind());
+ llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds));
+ ti = ds.Type;
+ scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal
+ : eValueTypeVariableStatic;
+ name = ds.Name;
+ section = ds.Segment;
+ offset = ds.DataOffset;
+ addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset);
+ break;
+ }
+ case S_GTHREAD32:
+ is_external = true;
+ LLVM_FALLTHROUGH;
+ case S_LTHREAD32: {
+ ThreadLocalDataSym tlds(sym.kind());
+ llvm::cantFail(
+ SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds));
+ ti = tlds.Type;
+ name = tlds.Name;
+ section = tlds.Segment;
+ offset = tlds.DataOffset;
+ addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset);
+ scope = eValueTypeVariableThreadLocal;
+ break;
+ }
+ default:
+ llvm_unreachable("unreachable!");
+ }
+
+ CompUnitSP comp_unit;
+ llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr);
+ if (modi) {
+ CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi);
+ comp_unit = GetOrCreateCompileUnit(cci);
+ }
+
+ Declaration decl;
+ PdbTypeSymId tid(ti, false);
+ SymbolFileTypeSP type_sp =
+ std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
+ Variable::RangeList ranges;
+
+ m_ast->GetOrCreateVariableDecl(var_id);
+
+ DWARFExpression location = MakeGlobalLocationExpression(
+ section, offset, GetObjectFile()->GetModule());
+
+ std::string global_name("::");
+ global_name += name;
+ VariableSP var_sp = std::make_shared<Variable>(
+ toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp,
+ scope, comp_unit.get(), ranges, &decl, location, is_external, false,
+ false);
+ var_sp->SetLocationIsConstantValueData(false);
+
+ return var_sp;
+}
+
+lldb::VariableSP
+SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
+ const CVSymbol &cvs) {
+ TpiStream &tpi = m_index->tpi();
+ ConstantSym constant(cvs.kind());
+
+ llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant));
+ std::string global_name("::");
+ global_name += constant.Name;
+ PdbTypeSymId tid(constant.Type, false);
+ SymbolFileTypeSP type_sp =
+ std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid));
+
+ Declaration decl;
+ Variable::RangeList ranges;
+ ModuleSP module = GetObjectFile()->GetModule();
+ DWARFExpression location = MakeConstantLocationExpression(
+ constant.Type, tpi, constant.Value, module);
+
+ VariableSP var_sp = std::make_shared<Variable>(
+ toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
+ type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location,
+ false, false, false);
+ var_sp->SetLocationIsConstantValueData(true);
+ return var_sp;
+}
+
+VariableSP
+SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) {
+ auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr);
+ if (emplace_result.second)
+ emplace_result.first->second = CreateGlobalVariable(var_id);
+
+ return emplace_result.first->second;
+}
+
+lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) {
+ return GetOrCreateType(PdbTypeSymId(ti, false));
+}
+
+FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,
+ CompileUnit &comp_unit) {
+ auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
+ if (emplace_result.second)
+ emplace_result.first->second = CreateFunction(func_id, comp_unit);
+
+ return emplace_result.first->second;
+}
+
+CompUnitSP
+SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) {
+
+ auto emplace_result =
+ m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr);
+ if (emplace_result.second)
+ emplace_result.first->second = CreateCompileUnit(cci);
+
+ lldbassert(emplace_result.first->second);
+ return emplace_result.first->second;
+}
+
+Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {
+ auto iter = m_blocks.find(toOpaqueUid(block_id));
+ if (iter != m_blocks.end())
+ return *iter->second;
+
+ return CreateBlock(block_id);
+}
+
+void SymbolFileNativePDB::ParseDeclsForContext(
+ lldb_private::CompilerDeclContext decl_ctx) {
+ clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx);
+ if (!context)
+ return;
+ m_ast->ParseDeclsForContext(*context);
+}
+
+lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
+ if (index >= GetNumCompileUnits())
+ return CompUnitSP();
+ lldbassert(index < UINT16_MAX);
+ if (index >= UINT16_MAX)
+ return nullptr;
+
+ CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index);
+
+ return GetOrCreateCompileUnit(item);
+}
+
+lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) {
+ PdbSymUid uid(comp_unit.GetID());
+ lldbassert(uid.kind() == PdbSymUidKind::Compiland);
+
+ CompilandIndexItem *item =
+ m_index->compilands().GetCompiland(uid.asCompiland().modi);
+ lldbassert(item);
+ if (!item->m_compile_opts)
+ return lldb::eLanguageTypeUnknown;
+
+ return TranslateLanguage(item->m_compile_opts->getLanguage());
+}
+
+void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; }
+
+size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) {
+ PdbSymUid uid{comp_unit.GetID()};
+ lldbassert(uid.kind() == PdbSymUidKind::Compiland);
+ uint16_t modi = uid.asCompiland().modi;
+ CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi);
+
+ size_t count = comp_unit.GetNumFunctions();
+ const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray();
+ for (auto iter = syms.begin(); iter != syms.end(); ++iter) {
+ if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32)
+ continue;
+
+ PdbCompilandSymId sym_id{modi, iter.offset()};
+
+ FunctionSP func = GetOrCreateFunction(sym_id, comp_unit);
+ }
+
+ size_t new_count = comp_unit.GetNumFunctions();
+ lldbassert(new_count >= count);
+ return new_count - count;
+}
+
+static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) {
+ // If any of these flags are set, we need to resolve the compile unit.
+ uint32_t flags = eSymbolContextCompUnit;
+ flags |= eSymbolContextVariable;
+ flags |= eSymbolContextFunction;
+ flags |= eSymbolContextBlock;
+ flags |= eSymbolContextLineEntry;
+ return (resolve_scope & flags) != 0;
+}
+
+uint32_t SymbolFileNativePDB::ResolveSymbolContext(
+ const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) {
+ uint32_t resolved_flags = 0;
+ lldb::addr_t file_addr = addr.GetFileAddress();
+
+ if (NeedsResolvedCompileUnit(resolve_scope)) {
+ llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr);
+ if (!modi)
+ return 0;
+ CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi);
+ if (!cci)
+ return 0;
+
+ sc.comp_unit = GetOrCreateCompileUnit(*cci).get();
+ resolved_flags |= eSymbolContextCompUnit;
+ }
+
+ if (resolve_scope & eSymbolContextFunction ||
+ resolve_scope & eSymbolContextBlock) {
+ lldbassert(sc.comp_unit);
+ std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
+ // Search the matches in reverse. This way if there are multiple matches
+ // (for example we are 3 levels deep in a nested scope) it will find the
+ // innermost one first.
+ for (const auto &match : llvm::reverse(matches)) {
+ if (match.uid.kind() != PdbSymUidKind::CompilandSym)
+ continue;
+
+ PdbCompilandSymId csid = match.uid.asCompilandSym();
+ CVSymbol cvs = m_index->ReadSymbolRecord(csid);
+ PDB_SymType type = CVSymToPDBSym(cvs.kind());
+ if (type != PDB_SymType::Function && type != PDB_SymType::Block)
+ continue;
+ if (type == PDB_SymType::Function) {
+ sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
+ sc.block = sc.GetFunctionBlock();
+ }
+
+ if (type == PDB_SymType::Block) {
+ sc.block = &GetOrCreateBlock(csid);
+ sc.function = sc.block->CalculateSymbolContextFunction();
+ }
+ resolved_flags |= eSymbolContextFunction;
+ resolved_flags |= eSymbolContextBlock;
+ break;
+ }
+ }
+
+ if (resolve_scope & eSymbolContextLineEntry) {
+ lldbassert(sc.comp_unit);
+ if (auto *line_table = sc.comp_unit->GetLineTable()) {
+ if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
+ resolved_flags |= eSymbolContextLineEntry;
+ }
+ }
+
+ return resolved_flags;
+}
+
+uint32_t SymbolFileNativePDB::ResolveSymbolContext(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
+ return 0;
+}
+
+static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence,
+ const CompilandIndexItem &cci,
+ lldb::addr_t base_addr,
+ uint32_t file_number,
+ const LineFragmentHeader &block,
+ const LineNumberEntry &cur) {
+ LineInfo cur_info(cur.Flags);
+
+ if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto())
+ return;
+
+ uint64_t addr = base_addr + cur.Offset;
+
+ bool is_statement = cur_info.isStatement();
+ bool is_prologue = IsFunctionPrologue(cci, addr);
+ bool is_epilogue = IsFunctionEpilogue(cci, addr);
+
+ uint32_t lno = cur_info.getStartLine();
+
+ table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number,
+ is_statement, false, is_prologue, is_epilogue,
+ false);
+}
+
+static void TerminateLineSequence(LineTable &table,
+ const LineFragmentHeader &block,
+ lldb::addr_t base_addr, uint32_t file_number,
+ uint32_t last_line,
+ std::unique_ptr<LineSequence> seq) {
+ // The end is always a terminal entry, so insert it regardless.
+ table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize,
+ last_line, 0, file_number, false, false,
+ false, false, true);
+ table.InsertSequence(seq.release());
+}
+
+bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
+ // Unfortunately LLDB is set up to parse the entire compile unit line table
+ // all at once, even if all it really needs is line info for a specific
+ // function. In the future it would be nice if it could set the sc.m_function
+ // member, and we could only get the line info for the function in question.
+ PdbSymUid cu_id(comp_unit.GetID());
+ lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
+ CompilandIndexItem *cci =
+ m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
+ lldbassert(cci);
+ auto line_table = llvm::make_unique<LineTable>(&comp_unit);
+
+ // This is basically a copy of the .debug$S subsections from all original COFF
+ // object files merged together with address relocations applied. We are
+ // looking for all DEBUG_S_LINES subsections.
+ for (const DebugSubsectionRecord &dssr :
+ cci->m_debug_stream.getSubsectionsArray()) {
+ if (dssr.kind() != DebugSubsectionKind::Lines)
+ continue;
+
+ DebugLinesSubsectionRef lines;
+ llvm::BinaryStreamReader reader(dssr.getRecordData());
+ if (auto EC = lines.initialize(reader)) {
+ llvm::consumeError(std::move(EC));
+ return false;
+ }
+
+ const LineFragmentHeader *lfh = lines.header();
+ uint64_t virtual_addr =
+ m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset);
+
+ const auto &checksums = cci->m_strings.checksums().getArray();
+ const auto &strings = cci->m_strings.strings();
+ for (const LineColumnEntry &group : lines) {
+ // Indices in this structure are actually offsets of records in the
+ // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index
+ // into the global PDB string table.
+ auto iter = checksums.at(group.NameIndex);
+ if (iter == checksums.end())
+ continue;
+
+ llvm::Expected<llvm::StringRef> efn =
+ strings.getString(iter->FileNameOffset);
+ if (!efn) {
+ llvm::consumeError(efn.takeError());
+ continue;
+ }
+
+ // LLDB wants the index of the file in the list of support files.
+ auto fn_iter = llvm::find(cci->m_file_list, *efn);
+ lldbassert(fn_iter != cci->m_file_list.end());
+ // LLDB support file indices are 1-based.
+ uint32_t file_index =
+ 1 + std::distance(cci->m_file_list.begin(), fn_iter);
+
+ std::unique_ptr<LineSequence> sequence(
+ line_table->CreateLineSequenceContainer());
+ lldbassert(!group.LineNumbers.empty());
+
+ for (const LineNumberEntry &entry : group.LineNumbers) {
+ AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr,
+ file_index, *lfh, entry);
+ }
+ LineInfo last_line(group.LineNumbers.back().Flags);
+ TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index,
+ last_line.getEndLine(), std::move(sequence));
+ }
+ }
+
+ if (line_table->GetSize() == 0)
+ return false;
+
+ comp_unit.SetLineTable(line_table.release());
+ return true;
+}
+
+bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) {
+ // PDB doesn't contain information about macros
+ return false;
+}
+
+bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) {
+ PdbSymUid cu_id(comp_unit.GetID());
+ lldbassert(cu_id.kind() == PdbSymUidKind::Compiland);
+ CompilandIndexItem *cci =
+ m_index->compilands().GetCompiland(cu_id.asCompiland().modi);
+ lldbassert(cci);
+
+ for (llvm::StringRef f : cci->m_file_list) {
+ FileSpec::Style style =
+ f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows;
+ FileSpec spec(f, style);
+ support_files.Append(spec);
+ }
+
+ llvm::SmallString<64> main_source_file =
+ m_index->compilands().GetMainSourceFile(*cci);
+ FileSpec::Style style = main_source_file.startswith("/")
+ ? FileSpec::Style::posix
+ : FileSpec::Style::windows;
+ FileSpec spec(main_source_file, style);
+ support_files.Insert(0, spec);
+ return true;
+}
+
+bool SymbolFileNativePDB::ParseImportedModules(
+ const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
+ // PDB does not yet support module debug info
+ return false;
+}
+
+size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) {
+ GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym());
+ // FIXME: Parse child blocks
+ return 1;
+}
+
+void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); }
+
+uint32_t SymbolFileNativePDB::FindGlobalVariables(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches, VariableList &variables) {
+ using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
+
+ std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName(
+ name.GetStringRef(), m_index->symrecords());
+ for (const SymbolAndOffset &result : results) {
+ VariableSP var;
+ switch (result.second.kind()) {
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32:
+ case SymbolKind::S_GTHREAD32:
+ case SymbolKind::S_LTHREAD32:
+ case SymbolKind::S_CONSTANT: {
+ PdbGlobalSymId global(result.first, false);
+ var = GetOrCreateGlobalVariable(global);
+ variables.AddVariable(var);
+ break;
+ }
+ default:
+ continue;
+ }
+ }
+ return variables.GetSize();
+}
+
+uint32_t SymbolFileNativePDB::FindFunctions(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ FunctionNameType name_type_mask, bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ // For now we only support lookup by method name.
+ if (!(name_type_mask & eFunctionNameTypeMethod))
+ return 0;
+
+ using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>;
+
+ std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName(
+ name.GetStringRef(), m_index->symrecords());
+ for (const SymbolAndOffset &match : matches) {
+ if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF)
+ continue;
+ ProcRefSym proc(match.second.kind());
+ cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc));
+
+ if (!IsValidRecord(proc))
+ continue;
+
+ CompilandIndexItem &cci =
+ m_index->compilands().GetOrCreateCompiland(proc.modi());
+ SymbolContext sc;
+
+ sc.comp_unit = GetOrCreateCompileUnit(cci).get();
+ PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
+ sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
+
+ sc_list.Append(sc);
+ }
+
+ return sc_list.GetSize();
+}
+
+uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ return 0;
+}
+
+uint32_t SymbolFileNativePDB::FindTypes(
+ const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
+ bool append, uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
+ if (!append)
+ types.Clear();
+ if (!name)
+ return 0;
+
+ searched_symbol_files.clear();
+ searched_symbol_files.insert(this);
+
+ // There is an assumption 'name' is not a regex
+ size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types);
+
+ return match_count;
+}
+
+size_t
+SymbolFileNativePDB::FindTypes(const std::vector<CompilerContext> &context,
+ bool append, TypeMap &types) {
+ return 0;
+}
+
+size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
+ uint32_t max_matches,
+ TypeMap &types) {
+
+ size_t match_count = 0;
+ std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name);
+ if (max_matches > 0 && max_matches < matches.size())
+ matches.resize(max_matches);
+
+ for (TypeIndex ti : matches) {
+ TypeSP type = GetOrCreateType(ti);
+ if (!type)
+ continue;
+
+ types.Insert(type);
+ ++match_count;
+ }
+ return match_count;
+}
+
+size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) {
+ // Only do the full type scan the first time.
+ if (m_done_full_type_scan)
+ return 0;
+
+ size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+ LazyRandomTypeCollection &types = m_index->tpi().typeCollection();
+
+ // First process the entire TPI stream.
+ for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) {
+ TypeSP type = GetOrCreateType(*ti);
+ if (type)
+ (void)type->GetFullCompilerType();
+ }
+
+ // Next look for S_UDT records in the globals stream.
+ for (const uint32_t gid : m_index->globals().getGlobalsTable()) {
+ PdbGlobalSymId global{gid, false};
+ CVSymbol sym = m_index->ReadSymbolRecord(global);
+ if (sym.kind() != S_UDT)
+ continue;
+
+ UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+ bool is_typedef = true;
+ if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) {
+ CVType cvt = m_index->tpi().getType(udt.Type);
+ llvm::StringRef name = CVTagRecord::create(cvt).name();
+ if (name == udt.Name)
+ is_typedef = false;
+ }
+
+ if (is_typedef)
+ GetOrCreateTypedef(global);
+ }
+
+ size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize();
+
+ m_done_full_type_scan = true;
+
+ return new_count - old_count;
+}
+
+size_t
+SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
+ VariableList &variables) {
+ PdbSymUid sym_uid(comp_unit.GetID());
+ lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
+ return 0;
+}
+
+VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
+ PdbCompilandSymId var_id,
+ bool is_param) {
+ ModuleSP module = GetObjectFile()->GetModule();
+ VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module);
+ if (!var_info.location || !var_info.ranges)
+ return nullptr;
+
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
+ CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
+ TypeSP type_sp = GetOrCreateType(var_info.type);
+ std::string name = var_info.name.str();
+ Declaration decl;
+ SymbolFileTypeSP sftype =
+ std::make_shared<SymbolFileType>(*this, type_sp->GetID());
+
+ ValueType var_scope =
+ is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
+ VariableSP var_sp = std::make_shared<Variable>(
+ toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
+ comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false,
+ false, false);
+
+ if (!is_param)
+ m_ast->GetOrCreateVariableDecl(scope_id, var_id);
+
+ m_local_variables[toOpaqueUid(var_id)] = var_sp;
+ return var_sp;
+}
+
+VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
+ PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
+ auto iter = m_local_variables.find(toOpaqueUid(var_id));
+ if (iter != m_local_variables.end())
+ return iter->second;
+
+ return CreateLocalVariable(scope_id, var_id, is_param);
+}
+
+TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
+ CVSymbol sym = m_index->ReadSymbolRecord(id);
+ lldbassert(sym.kind() == SymbolKind::S_UDT);
+
+ UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym));
+
+ TypeSP target_type = GetOrCreateType(udt.Type);
+
+ (void)m_ast->GetOrCreateTypedefDecl(id);
+
+ Declaration decl;
+ return std::make_shared<lldb_private::Type>(
+ toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(),
+ nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID,
+ decl, target_type->GetForwardCompilerType(),
+ lldb_private::Type::eResolveStateForward);
+}
+
+TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) {
+ auto iter = m_types.find(toOpaqueUid(id));
+ if (iter != m_types.end())
+ return iter->second;
+
+ return CreateTypedef(id);
+}
+
+size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
+ Block &block = GetOrCreateBlock(block_id);
+
+ size_t count = 0;
+
+ CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
+ CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
+ uint32_t params_remaining = 0;
+ switch (sym.kind()) {
+ case S_GPROC32:
+ case S_LPROC32: {
+ ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
+ CVType signature = m_index->tpi().getType(proc.FunctionType);
+ ProcedureRecord sig;
+ cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig));
+ params_remaining = sig.getParameterCount();
+ break;
+ }
+ case S_BLOCK32:
+ break;
+ default:
+ lldbassert(false && "Symbol is not a block!");
+ return 0;
+ }
+
+ VariableListSP variables = block.GetBlockVariableList(false);
+ if (!variables) {
+ variables = std::make_shared<VariableList>();
+ block.SetVariableList(variables);
+ }
+
+ CVSymbolArray syms = limitSymbolArrayToScope(
+ cii->m_debug_stream.getSymbolArray(), block_id.offset);
+
+ // Skip the first record since it's a PROC32 or BLOCK32, and there's
+ // no point examining it since we know it's not a local variable.
+ syms.drop_front();
+ auto iter = syms.begin();
+ auto end = syms.end();
+
+ while (iter != end) {
+ uint32_t record_offset = iter.offset();
+ CVSymbol variable_cvs = *iter;
+ PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
+ ++iter;
+
+ // If this is a block, recurse into its children and then skip it.
+ if (variable_cvs.kind() == S_BLOCK32) {
+ uint32_t block_end = getScopeEndOffset(variable_cvs);
+ count += ParseVariablesForBlock(child_sym_id);
+ iter = syms.at(block_end);
+ continue;
+ }
+
+ bool is_param = params_remaining > 0;
+ VariableSP variable;
+ switch (variable_cvs.kind()) {
+ case S_REGREL32:
+ case S_REGISTER:
+ case S_LOCAL:
+ variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
+ if (is_param)
+ --params_remaining;
+ if (variable)
+ variables->AddVariableIfUnique(variable);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Pass false for set_children, since we call this recursively so that the
+ // children will call this for themselves.
+ block.SetDidParseVariables(true, false);
+
+ return count;
+}
+
+size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
+ lldbassert(sc.function || sc.comp_unit);
+
+ VariableListSP variables;
+ if (sc.block) {
+ PdbSymUid block_id(sc.block->GetID());
+
+ size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
+ return count;
+ }
+
+ if (sc.function) {
+ PdbSymUid block_id(sc.function->GetID());
+
+ size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
+ return count;
+ }
+
+ if (sc.comp_unit) {
+ variables = sc.comp_unit->GetVariableList(false);
+ if (!variables) {
+ variables = std::make_shared<VariableList>();
+ sc.comp_unit->SetVariableList(variables);
+ }
+ return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
+ }
+
+ llvm_unreachable("Unreachable!");
+}
+
+CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
+ clang::Decl *decl = m_ast->GetOrCreateDeclForUid(PdbSymUid(uid));
+
+ return m_ast->ToCompilerDecl(*decl);
+}
+
+CompilerDeclContext
+SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
+ clang::DeclContext *context =
+ m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid));
+ if (!context)
+ return {};
+
+ return m_ast->ToCompilerDeclContext(*context);
+}
+
+CompilerDeclContext
+SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
+ clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid));
+ return m_ast->ToCompilerDeclContext(*context);
+}
+
+Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+ auto iter = m_types.find(type_uid);
+ // lldb should not be passing us non-sensical type uids. the only way it
+ // could have a type uid in the first place is if we handed it out, in which
+ // case we should know about the type. However, that doesn't mean we've
+ // instantiated it yet. We can vend out a UID for a future type. So if the
+ // type doesn't exist, let's instantiate it now.
+ if (iter != m_types.end())
+ return &*iter->second;
+
+ PdbSymUid uid(type_uid);
+ lldbassert(uid.kind() == PdbSymUidKind::Type);
+ PdbTypeSymId type_id = uid.asTypeSym();
+ if (type_id.index.isNoneType())
+ return nullptr;
+
+ TypeSP type_sp = CreateAndCacheType(type_id);
+ return &*type_sp;
+}
+
+llvm::Optional<SymbolFile::ArrayInfo>
+SymbolFileNativePDB::GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+ return llvm::None;
+}
+
+
+bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
+ clang::QualType qt =
+ clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType());
+
+ return m_ast->CompleteType(qt);
+}
+
+size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
+ TypeClass type_mask,
+ lldb_private::TypeList &type_list) {
+ return 0;
+}
+
+CompilerDeclContext
+SymbolFileNativePDB::FindNamespace(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) {
+ return {};
+}
+
+TypeSystem *
+SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
+ auto type_system =
+ m_obj_file->GetModule()->GetTypeSystemForLanguage(language);
+ if (type_system)
+ type_system->SetSymbolFile(this);
+ return type_system;
+}
+
+ConstString SymbolFileNativePDB::GetPluginName() {
+ static ConstString g_name("pdb");
+ return g_name;
+}
+
+uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; }
diff --git a/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
new file mode 100644
index 000000000000..dcf3fe365ef1
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -0,0 +1,245 @@
+//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
+#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H
+
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/SymbolFile.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include "CompileUnitIndex.h"
+#include "PdbIndex.h"
+
+namespace clang {
+class TagDecl;
+}
+
+namespace llvm {
+namespace codeview {
+class ClassRecord;
+class EnumRecord;
+class ModifierRecord;
+class PointerRecord;
+struct UnionRecord;
+} // namespace codeview
+} // namespace llvm
+
+namespace lldb_private {
+class ClangASTImporter;
+
+namespace npdb {
+class PdbAstBuilder;
+
+class SymbolFileNativePDB : public SymbolFile {
+ friend class UdtRecordCompleter;
+
+public:
+ //------------------------------------------------------------------
+ // Static Functions
+ //------------------------------------------------------------------
+ static void Initialize();
+
+ static void Terminate();
+
+ static void DebuggerInitialize(Debugger &debugger);
+
+ static ConstString GetPluginNameStatic();
+
+ static const char *GetPluginDescriptionStatic();
+
+ static SymbolFile *CreateInstance(ObjectFile *obj_file);
+
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ SymbolFileNativePDB(ObjectFile *ofile);
+
+ ~SymbolFileNativePDB() override;
+
+ uint32_t CalculateAbilities() override;
+
+ void InitializeObject() override;
+
+ //------------------------------------------------------------------
+ // Compile Unit function calls
+ //------------------------------------------------------------------
+
+ uint32_t GetNumCompileUnits() override;
+
+ void
+ ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
+
+ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
+
+ lldb::LanguageType
+ ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
+
+ size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
+
+ bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+ FileSpecList &support_files) override;
+ size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
+
+ bool
+ ParseImportedModules(const SymbolContext &sc,
+ std::vector<ConstString> &imported_modules) override;
+
+ size_t ParseBlocksRecursive(Function &func) override;
+
+ uint32_t FindGlobalVariables(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches,
+ VariableList &variables) override;
+
+ size_t ParseVariablesForContext(const SymbolContext &sc) override;
+
+ void AddSymbols(Symtab &symtab) override;
+
+ CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
+ CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override;
+ CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override;
+ Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override;
+
+ bool CompleteType(CompilerType &compiler_type) override;
+ uint32_t ResolveSymbolContext(const Address &so_addr,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContext &sc) override;
+ uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line,
+ bool check_inlines,
+ lldb::SymbolContextItem resolve_scope,
+ SymbolContextList &sc_list) override;
+
+ size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
+ TypeList &type_list) override;
+
+ uint32_t FindFunctions(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ lldb::FunctionNameType name_type_mask,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) override;
+
+ uint32_t FindFunctions(const RegularExpression &regex, bool include_inlines,
+ bool append, SymbolContextList &sc_list) override;
+
+ uint32_t FindTypes(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx, bool append,
+ uint32_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeMap &types) override;
+
+ size_t FindTypes(const std::vector<CompilerContext> &context, bool append,
+ TypeMap &types) override;
+
+ TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override;
+
+ CompilerDeclContext
+ FindNamespace(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx) override;
+
+ ConstString GetPluginName() override;
+
+ uint32_t GetPluginVersion() override;
+
+ llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); }
+ const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); }
+
+ void DumpClangAST(Stream &s) override;
+
+private:
+
+ size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches,
+ TypeMap &types);
+
+ lldb::TypeSP CreateModifierType(PdbTypeSymId type_id,
+ const llvm::codeview::ModifierRecord &mr,
+ CompilerType ct);
+ lldb::TypeSP CreatePointerType(PdbTypeSymId type_id,
+ const llvm::codeview::PointerRecord &pr,
+ CompilerType ct);
+ lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct);
+ lldb::TypeSP CreateTagType(PdbTypeSymId type_id,
+ const llvm::codeview::ClassRecord &cr,
+ CompilerType ct);
+ lldb::TypeSP CreateTagType(PdbTypeSymId type_id,
+ const llvm::codeview::EnumRecord &er,
+ CompilerType ct);
+ lldb::TypeSP CreateTagType(PdbTypeSymId type_id,
+ const llvm::codeview::UnionRecord &ur,
+ CompilerType ct);
+ lldb::TypeSP CreateArrayType(PdbTypeSymId type_id,
+ const llvm::codeview::ArrayRecord &ar,
+ CompilerType ct);
+ lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id,
+ const llvm::codeview::ProcedureRecord &pr,
+ CompilerType ct);
+ lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id,
+ const llvm::codeview::TagRecord &record,
+ size_t size, CompilerType ct);
+
+ lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id,
+ CompileUnit &comp_unit);
+ lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci);
+ lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id);
+ lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti);
+ lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id);
+ Block &GetOrCreateBlock(PdbCompilandSymId block_id);
+ lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id,
+ PdbCompilandSymId var_id,
+ bool is_param);
+ lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id);
+
+ lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id,
+ CompileUnit &comp_unit);
+ Block &CreateBlock(PdbCompilandSymId block_id);
+ lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id,
+ PdbCompilandSymId var_id, bool is_param);
+ lldb::TypeSP CreateTypedef(PdbGlobalSymId id);
+ lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci);
+ lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct);
+ lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id);
+ lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id);
+ lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id,
+ const llvm::codeview::CVSymbol &cvs);
+ size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit,
+ VariableList &variables);
+ size_t ParseVariablesForBlock(PdbCompilandSymId block_id);
+
+ llvm::BumpPtrAllocator m_allocator;
+
+ lldb::addr_t m_obj_load_address = 0;
+ bool m_done_full_type_scan = false;
+
+ std::unique_ptr<PdbIndex> m_index;
+
+ std::unique_ptr<PdbAstBuilder> m_ast;
+
+ llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_global_vars;
+ llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_local_variables;
+ llvm::DenseMap<lldb::user_id_t, lldb::BlockSP> m_blocks;
+ llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions;
+ llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands;
+ llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;
+};
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_
diff --git a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
new file mode 100644
index 000000000000..239dfbee625d
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -0,0 +1,191 @@
+#include "UdtRecordCompleter.h"
+
+#include "PdbAstBuilder.h"
+#include "PdbIndex.h"
+#include "PdbSymUid.h"
+#include "PdbUtil.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+
+using Error = llvm::Error;
+
+UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id,
+ CompilerType &derived_ct,
+ clang::TagDecl &tag_decl,
+ PdbAstBuilder &ast_builder,
+ TpiStream &tpi)
+ : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
+ m_ast_builder(ast_builder), m_tpi(tpi) {
+ CVType cvt = m_tpi.getType(m_id.index);
+ switch (cvt.kind()) {
+ case LF_ENUM:
+ llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
+ break;
+ case LF_UNION:
+ llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, m_cvr.ur));
+ break;
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, m_cvr.cr));
+ break;
+ default:
+ llvm_unreachable("unreachable!");
+ }
+}
+
+clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex(
+ llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access) {
+ PdbTypeSymId type_id(ti);
+ clang::QualType qt = m_ast_builder.GetOrCreateType(type_id);
+
+ CVType udt_cvt = m_tpi.getType(ti);
+
+ std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
+ m_ast_builder.clang().CreateBaseClassSpecifier(
+ qt.getAsOpaquePtr(), TranslateMemberAccess(access), false,
+ udt_cvt.kind() == LF_CLASS);
+ lldbassert(base_spec);
+ m_bases.push_back(std::move(base_spec));
+ return qt;
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ BaseClassRecord &base) {
+ clang::QualType base_qt =
+ AddBaseClassForTypeIndex(base.Type, base.getAccess());
+
+ auto decl =
+ m_ast_builder.clang().GetAsCXXRecordDecl(base_qt.getAsOpaquePtr());
+ lldbassert(decl);
+
+ auto offset = clang::CharUnits::fromQuantity(base.getBaseOffset());
+ m_layout.base_offsets.insert(std::make_pair(decl, offset));
+
+ return llvm::Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ VirtualBaseClassRecord &base) {
+ AddBaseClassForTypeIndex(base.BaseType, base.getAccess());
+
+ // FIXME: Handle virtual base offsets.
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ ListContinuationRecord &cont) {
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ VFPtrRecord &vfptr) {
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(
+ CVMemberRecord &cvr, StaticDataMemberRecord &static_data_member) {
+ clang::QualType member_type =
+ m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type));
+
+ m_ast_builder.CompleteType(member_type);
+
+ CompilerType member_ct = m_ast_builder.ToCompilerType(member_type);
+
+ lldb::AccessType access =
+ TranslateMemberAccess(static_data_member.getAccess());
+ ClangASTContext::AddVariableToRecordType(
+ m_derived_ct, static_data_member.Name, member_ct, access);
+
+ // FIXME: Add a PdbSymUid namespace for field list members and update
+ // the m_uid_to_decl map with this decl.
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ NestedTypeRecord &nested) {
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ DataMemberRecord &data_member) {
+
+ uint64_t offset = data_member.FieldOffset * 8;
+ uint32_t bitfield_width = 0;
+
+ TypeIndex ti(data_member.Type);
+ if (!ti.isSimple()) {
+ CVType cvt = m_tpi.getType(ti);
+ if (cvt.kind() == LF_BITFIELD) {
+ BitFieldRecord bfr;
+ llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, bfr));
+ offset += bfr.BitOffset;
+ bitfield_width = bfr.BitSize;
+ ti = bfr.Type;
+ }
+ }
+
+ clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti));
+ m_ast_builder.CompleteType(member_qt);
+
+ lldb::AccessType access = TranslateMemberAccess(data_member.getAccess());
+
+ clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType(
+ m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt),
+ access, bitfield_width);
+ // FIXME: Add a PdbSymUid namespace for field list members and update
+ // the m_uid_to_decl map with this decl.
+
+ m_layout.field_offsets.insert(std::make_pair(decl, offset));
+
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ OneMethodRecord &one_method) {
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ OverloadedMethodRecord &overloaded) {
+ return Error::success();
+}
+
+Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
+ EnumeratorRecord &enumerator) {
+ Declaration decl;
+ llvm::StringRef name = DropNameScope(enumerator.getName());
+
+ m_ast_builder.clang().AddEnumerationValueToEnumerationType(
+ m_derived_ct, decl, name.str().c_str(), enumerator.Value);
+ return Error::success();
+}
+
+void UdtRecordCompleter::complete() {
+ ClangASTContext &clang = m_ast_builder.clang();
+ clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(),
+ std::move(m_bases));
+
+ clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType());
+ ClangASTContext::BuildIndirectFields(m_derived_ct);
+ ClangASTContext::CompleteTagDeclarationDefinition(m_derived_ct);
+
+ if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
+ m_ast_builder.importer().InsertRecordDecl(record_decl, m_layout);
+ }
+}
diff --git a/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
new file mode 100644
index 000000000000..469685126e59
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -0,0 +1,75 @@
+//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
+#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
+
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "llvm/DebugInfo/CodeView/CVRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+
+#include "PdbSymUid.h"
+
+namespace clang {
+class CXXBaseSpecifier;
+class QualType;
+class TagDecl;
+} // namespace clang
+
+namespace llvm {
+namespace pdb {
+class TpiStream;
+}
+} // namespace llvm
+
+namespace lldb_private {
+class Type;
+class CompilerType;
+namespace npdb {
+class PdbAstBuilder;
+
+class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
+ union UdtTagRecord {
+ UdtTagRecord() {}
+ llvm::codeview::UnionRecord ur;
+ llvm::codeview::ClassRecord cr;
+ llvm::codeview::EnumRecord er;
+ } m_cvr;
+
+ PdbTypeSymId m_id;
+ CompilerType &m_derived_ct;
+ clang::TagDecl &m_tag_decl;
+ PdbAstBuilder &m_ast_builder;
+ llvm::pdb::TpiStream &m_tpi;
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> m_bases;
+ ClangASTImporter::LayoutInfo m_layout;
+
+public:
+ UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct,
+ clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder,
+ llvm::pdb::TpiStream &tpi);
+
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \
+ llvm::codeview::Name##Record &Record) override;
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+
+ void complete();
+
+private:
+ clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti,
+ llvm::codeview::MemberAccess access);
+};
+
+} // namespace npdb
+} // namespace lldb_private
+
+#endif // LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H
diff --git a/source/Plugins/SymbolFile/PDB/CMakeLists.txt b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
index 1c176c32224d..19698a7187f7 100644
--- a/source/Plugins/SymbolFile/PDB/CMakeLists.txt
+++ b/source/Plugins/SymbolFile/PDB/CMakeLists.txt
@@ -9,6 +9,7 @@ add_lldb_library(lldbPluginSymbolFilePDB PLUGIN
lldbCore
lldbSymbol
lldbUtility
+ lldbPluginSymbolFileNativePDB
LINK_COMPONENTS
DebugInfoPDB
Support
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 8bea994aae5d..65e718bedaf1 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -9,14 +9,19 @@
#include "PDBASTParser.h"
+#include "SymbolFilePDB.h"
+
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
+#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/TypeSystem.h"
#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
@@ -33,12 +38,13 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+
using namespace lldb;
using namespace lldb_private;
using namespace llvm::pdb;
-namespace {
-int TranslateUdtKind(PDB_UdtType pdb_kind) {
+static int TranslateUdtKind(PDB_UdtType pdb_kind) {
switch (pdb_kind) {
case PDB_UdtType::Class:
return clang::TTK_Class;
@@ -49,10 +55,10 @@ int TranslateUdtKind(PDB_UdtType pdb_kind) {
case PDB_UdtType::Interface:
return clang::TTK_Interface;
}
- return -1;
+ llvm_unreachable("unsuported PDB UDT type");
}
-lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
+static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
switch (type) {
case PDB_BuiltinType::Float:
return lldb::eEncodingIEEE754;
@@ -73,7 +79,7 @@ lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) {
}
}
-lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
+static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
switch (type) {
case PDB_VariantType::Int8:
case PDB_VariantType::Int16:
@@ -94,7 +100,7 @@ lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) {
return lldb::eEncodingSint;
}
-CompilerType
+static CompilerType
GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
const PDBSymbolTypeBuiltin &pdb_type,
Encoding encoding, uint32_t width) {
@@ -109,6 +115,8 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
return CompilerType();
case PDB_BuiltinType::Void:
return clang_ast.GetBasicType(eBasicTypeVoid);
+ case PDB_BuiltinType::Char:
+ return clang_ast.GetBasicType(eBasicTypeChar);
case PDB_BuiltinType::Bool:
return clang_ast.GetBasicType(eBasicTypeBool);
case PDB_BuiltinType::Long:
@@ -143,8 +151,8 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast,
return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
}
-ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
- CompilerType &compiler_type) {
+static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
+ CompilerType &compiler_type) {
PDB_BuiltinType kind = pdb_type.getBuiltinType();
switch (kind) {
default:
@@ -175,7 +183,8 @@ ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type,
return compiler_type.GetTypeName();
}
-bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) {
+static bool GetDeclarationForSymbol(const PDBSymbol &symbol,
+ Declaration &decl) {
auto &raw_sym = symbol.getRawSymbol();
auto first_line_up = raw_sym.getSrcLineOnTypeDefn();
@@ -193,13 +202,159 @@ bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) {
if (!src_file_up)
return false;
- FileSpec spec(src_file_up->getFileName(), /*resolve_path*/ false);
+ FileSpec spec(src_file_up->getFileName());
decl.SetFile(spec);
decl.SetColumn(first_line_up->getColumnNumber());
decl.SetLine(first_line_up->getLineNumber());
return true;
}
-} // namespace
+
+static AccessType TranslateMemberAccess(PDB_MemberAccess access) {
+ switch (access) {
+ case PDB_MemberAccess::Private:
+ return eAccessPrivate;
+ case PDB_MemberAccess::Protected:
+ return eAccessProtected;
+ case PDB_MemberAccess::Public:
+ return eAccessPublic;
+ }
+ return eAccessNone;
+}
+
+static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) {
+ switch (udt_kind) {
+ case PDB_UdtType::Struct:
+ case PDB_UdtType::Union:
+ return eAccessPublic;
+ case PDB_UdtType::Class:
+ case PDB_UdtType::Interface:
+ return eAccessPrivate;
+ }
+ llvm_unreachable("unsupported PDB UDT type");
+}
+
+static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) {
+ AccessType access = TranslateMemberAccess(udt.getAccess());
+ if (access != lldb::eAccessNone || !udt.isNested())
+ return access;
+
+ auto parent = udt.getClassParent();
+ if (!parent)
+ return lldb::eAccessNone;
+
+ auto parent_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(parent.get());
+ if (!parent_udt)
+ return lldb::eAccessNone;
+
+ return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind());
+}
+
+static clang::MSInheritanceAttr::Spelling
+GetMSInheritance(const PDBSymbolTypeUDT &udt) {
+ int base_count = 0;
+ bool has_virtual = false;
+
+ auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
+ if (bases_enum) {
+ while (auto base = bases_enum->getNext()) {
+ base_count++;
+ has_virtual |= base->isVirtualBaseClass();
+ }
+ }
+
+ if (has_virtual)
+ return clang::MSInheritanceAttr::Keyword_virtual_inheritance;
+ if (base_count > 1)
+ return clang::MSInheritanceAttr::Keyword_multiple_inheritance;
+ return clang::MSInheritanceAttr::Keyword_single_inheritance;
+}
+
+static std::unique_ptr<llvm::pdb::PDBSymbol>
+GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) {
+ const IPDBSession &session = symbol.getSession();
+ const IPDBRawSymbol &raw = symbol.getRawSymbol();
+ auto tag = symbol.getSymTag();
+
+ // For items that are nested inside of a class, return the class that it is
+ // nested inside of.
+ // Note that only certain items can be nested inside of classes.
+ switch (tag) {
+ case PDB_SymType::Function:
+ case PDB_SymType::Data:
+ case PDB_SymType::UDT:
+ case PDB_SymType::Enum:
+ case PDB_SymType::FunctionSig:
+ case PDB_SymType::Typedef:
+ case PDB_SymType::BaseClass:
+ case PDB_SymType::VTable: {
+ auto class_parent_id = raw.getClassParentId();
+ if (auto class_parent = session.getSymbolById(class_parent_id))
+ return class_parent;
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Otherwise, if it is nested inside of a function, return the function.
+ // Note that only certain items can be nested inside of functions.
+ switch (tag) {
+ case PDB_SymType::Block:
+ case PDB_SymType::Data: {
+ auto lexical_parent_id = raw.getLexicalParentId();
+ auto lexical_parent = session.getSymbolById(lexical_parent_id);
+ if (!lexical_parent)
+ return nullptr;
+
+ auto lexical_parent_tag = lexical_parent->getSymTag();
+ if (lexical_parent_tag == PDB_SymType::Function)
+ return lexical_parent;
+ if (lexical_parent_tag == PDB_SymType::Exe)
+ return nullptr;
+
+ return GetClassOrFunctionParent(*lexical_parent);
+ }
+ default:
+ return nullptr;
+ }
+}
+
+static clang::NamedDecl *
+GetDeclFromContextByName(const clang::ASTContext &ast,
+ const clang::DeclContext &decl_context,
+ llvm::StringRef name) {
+ clang::IdentifierInfo &ident = ast.Idents.get(name);
+ clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident);
+ clang::DeclContext::lookup_result result = decl_context.lookup(decl_name);
+ if (result.empty())
+ return nullptr;
+
+ return result[0];
+}
+
+static bool IsAnonymousNamespaceName(llvm::StringRef name) {
+ return name == "`anonymous namespace'" || name == "`anonymous-namespace'";
+}
+
+static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) {
+ switch (pdb_cc) {
+ case llvm::codeview::CallingConvention::NearC:
+ return clang::CC_C;
+ case llvm::codeview::CallingConvention::NearStdCall:
+ return clang::CC_X86StdCall;
+ case llvm::codeview::CallingConvention::NearFast:
+ return clang::CC_X86FastCall;
+ case llvm::codeview::CallingConvention::ThisCall:
+ return clang::CC_X86ThisCall;
+ case llvm::codeview::CallingConvention::NearVector:
+ return clang::CC_X86VectorCall;
+ case llvm::codeview::CallingConvention::NearPascal:
+ return clang::CC_X86Pascal;
+ default:
+ assert(false && "Unknown calling convention");
+ return clang::CC_C;
+ }
+}
PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {}
@@ -208,76 +363,167 @@ PDBASTParser::~PDBASTParser() {}
// DebugInfoASTParser interface
lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
- // PDB doesn't maintain enough information to robustly rebuild the entire
- // tree, and this is most problematic when it comes to figure out the right
- // DeclContext to put a type in. So for now, everything goes in the
- // translation unit decl as a fully qualified type.
- clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl();
Declaration decl;
-
switch (type.getSymTag()) {
+ case PDB_SymType::BaseClass: {
+ auto symbol_file = m_ast.GetSymbolFile();
+ if (!symbol_file)
+ return nullptr;
+
+ auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId());
+ return ty ? ty->shared_from_this() : nullptr;
+ } break;
case PDB_SymType::UDT: {
auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type);
assert(udt);
- AccessType access = lldb::eAccessPublic;
- PDB_UdtType udt_kind = udt->getUdtKind();
- auto tag_type_kind = TranslateUdtKind(udt_kind);
- if (tag_type_kind == -1)
+
+ // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol
+ // other than a Typedef symbol in PDB. For example,
+ // typedef union { short Row; short Col; } Union;
+ // is generated as a named UDT in PDB:
+ // union Union { short Row; short Col; }
+ // Such symbols will be handled here.
+
+ // Some UDT with trival ctor has zero length. Just ignore.
+ if (udt->getLength() == 0)
+ return nullptr;
+
+ // Ignore unnamed-tag UDTs.
+ std::string name = MSVCUndecoratedNameParser::DropScope(udt->getName());
+ if (name.empty())
return nullptr;
- if (udt_kind == PDB_UdtType::Class)
- access = lldb::eAccessPrivate;
+ auto decl_context = GetDeclContextContainingSymbol(type);
- CompilerType clang_type = m_ast.CreateRecordType(
- tu_decl_ctx, access, udt->getName().c_str(), tag_type_kind,
- lldb::eLanguageTypeC_plus_plus, nullptr);
+ // Check if such an UDT already exists in the current context.
+ // This may occur with const or volatile types. There are separate type
+ // symbols in PDB for types with const or volatile modifiers, but we need
+ // to create only one declaration for them all.
+ Type::ResolveStateTag type_resolve_state_tag;
+ CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(
+ ConstString(name), decl_context);
+ if (!clang_type.IsValid()) {
+ auto access = GetAccessibilityForUdt(*udt);
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+ auto tag_type_kind = TranslateUdtKind(udt->getUdtKind());
+ ClangASTMetadata metadata;
+ metadata.SetUserID(type.getSymIndexId());
+ metadata.SetIsDynamicCXXType(false);
+
+ clang_type = m_ast.CreateRecordType(
+ decl_context, access, name.c_str(), tag_type_kind,
+ lldb::eLanguageTypeC_plus_plus, &metadata);
+ assert(clang_type.IsValid());
+
+ auto record_decl =
+ m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
+ assert(record_decl);
+ m_uid_to_decl[type.getSymIndexId()] = record_decl;
+
+ auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit(
+ *m_ast.getASTContext(), GetMSInheritance(*udt));
+ record_decl->addAttr(inheritance_attr);
+
+ ClangASTContext::StartTagDeclarationDefinition(clang_type);
+
+ auto children = udt->findAllChildren();
+ if (!children || children->getChildCount() == 0) {
+ // PDB does not have symbol of forwarder. We assume we get an udt w/o
+ // any fields. Just complete it at this point.
+ ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
+
+ ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
+ false);
+
+ type_resolve_state_tag = Type::eResolveStateFull;
+ } else {
+ // Add the type to the forward declarations. It will help us to avoid
+ // an endless recursion in CompleteTypeFromUdt function.
+ m_forward_decl_to_uid[record_decl] = type.getSymIndexId();
+
+ ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(),
+ true);
+
+ type_resolve_state_tag = Type::eResolveStateForward;
+ }
+ } else
+ type_resolve_state_tag = Type::eResolveStateForward;
+
+ if (udt->isConstType())
+ clang_type = clang_type.AddConstModifier();
+
+ if (udt->isVolatileType())
+ clang_type = clang_type.AddVolatileModifier();
+
+ GetDeclarationForSymbol(type, decl);
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);
+ type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
+ udt->getLength(), nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, clang_type,
+ type_resolve_state_tag);
} break;
case PDB_SymType::Enum: {
auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type);
assert(enum_type);
- auto underlying_type_up = enum_type->getUnderlyingType();
- if (!underlying_type_up)
- return nullptr;
- lldb::Encoding encoding =
- TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
- // FIXME: Type of underlying builtin is always `Int`. We correct it with
- // the very first enumerator's encoding if any.
- auto first_child = enum_type->findOneChild<PDBSymbolData>();
- if (first_child) {
- encoding = TranslateEnumEncoding(first_child->getValue().Type);
- }
- std::string name = enum_type->getName();
+
+ std::string name =
+ MSVCUndecoratedNameParser::DropScope(enum_type->getName());
+ auto decl_context = GetDeclContextContainingSymbol(type);
uint64_t bytes = enum_type->getLength();
- CompilerType builtin_type;
- if (bytes > 0)
- builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
- m_ast, *underlying_type_up, encoding, bytes * 8);
- else
- builtin_type = m_ast.GetBasicType(eBasicTypeInt);
- // FIXME: PDB does not have information about scoped enumeration (Enum
- // Class). Set it false for now.
- bool isScoped = false;
-
- CompilerType ast_enum = m_ast.CreateEnumerationType(
- name.c_str(), tu_decl_ctx, decl, builtin_type, isScoped);
- auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
- if (enum_values) {
- while (auto enum_value = enum_values->getNext()) {
- if (enum_value->getDataKind() != PDB_DataKind::Constant)
- continue;
- AddEnumValue(ast_enum, *enum_value);
+
+ // Check if such an enum already exists in the current context
+ CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>(
+ ConstString(name), decl_context);
+ if (!ast_enum.IsValid()) {
+ auto underlying_type_up = enum_type->getUnderlyingType();
+ if (!underlying_type_up)
+ return nullptr;
+
+ lldb::Encoding encoding =
+ TranslateBuiltinEncoding(underlying_type_up->getBuiltinType());
+ // FIXME: Type of underlying builtin is always `Int`. We correct it with
+ // the very first enumerator's encoding if any.
+ auto first_child = enum_type->findOneChild<PDBSymbolData>();
+ if (first_child)
+ encoding = TranslateEnumEncoding(first_child->getValue().Type);
+
+ CompilerType builtin_type;
+ if (bytes > 0)
+ builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize(
+ m_ast, *underlying_type_up, encoding, bytes * 8);
+ else
+ builtin_type = m_ast.GetBasicType(eBasicTypeInt);
+
+ // FIXME: PDB does not have information about scoped enumeration (Enum
+ // Class). Set it false for now.
+ bool isScoped = false;
+
+ ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl,
+ builtin_type, isScoped);
+
+ auto enum_decl = ClangASTContext::GetAsEnumDecl(ast_enum);
+ assert(enum_decl);
+ m_uid_to_decl[type.getSymIndexId()] = enum_decl;
+
+ auto enum_values = enum_type->findAllChildren<PDBSymbolData>();
+ if (enum_values) {
+ while (auto enum_value = enum_values->getNext()) {
+ if (enum_value->getDataKind() != PDB_DataKind::Constant)
+ continue;
+ AddEnumValue(ast_enum, *enum_value);
+ }
}
+
+ if (ClangASTContext::StartTagDeclarationDefinition(ast_enum))
+ ClangASTContext::CompleteTagDeclarationDefinition(ast_enum);
}
- if (ClangASTContext::StartTagDeclarationDefinition(ast_enum))
- ClangASTContext::CompleteTagDeclarationDefinition(ast_enum);
+
+ if (enum_type->isConstType())
+ ast_enum = ast_enum.AddConstModifier();
+
+ if (enum_type->isVolatileType())
+ ast_enum = ast_enum.AddVolatileModifier();
GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
@@ -288,23 +534,43 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
case PDB_SymType::Typedef: {
auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type);
assert(type_def);
+
lldb_private::Type *target_type =
m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
if (!target_type)
return nullptr;
- std::string name = type_def->getName();
- uint64_t bytes = type_def->getLength();
- CompilerType target_ast_type = target_type->GetFullCompilerType();
- CompilerDeclContext target_decl_ctx =
- m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID());
+
+ std::string name =
+ MSVCUndecoratedNameParser::DropScope(type_def->getName());
+ auto decl_ctx = GetDeclContextContainingSymbol(type);
+
+ // Check if such a typedef already exists in the current context
CompilerType ast_typedef =
- m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx);
- if (!ast_typedef)
- return nullptr;
+ m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(ConstString(name),
+ decl_ctx);
+ if (!ast_typedef.IsValid()) {
+ CompilerType target_ast_type = target_type->GetFullCompilerType();
+
+ ast_typedef = m_ast.CreateTypedefType(
+ target_ast_type, name.c_str(), CompilerDeclContext(&m_ast, decl_ctx));
+ if (!ast_typedef)
+ return nullptr;
+
+ auto typedef_decl = ClangASTContext::GetAsTypedefDecl(ast_typedef);
+ assert(typedef_decl);
+ m_uid_to_decl[type.getSymIndexId()] = typedef_decl;
+ }
+
+ if (type_def->isConstType())
+ ast_typedef = ast_typedef.AddConstModifier();
+
+ if (type_def->isVolatileType())
+ ast_typedef = ast_typedef.AddVolatileModifier();
+ GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name),
- bytes, nullptr, target_type->GetID(),
+ type_def->getLength(), nullptr, target_type->GetID(),
lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef,
lldb_private::Type::eResolveStateFull);
} break;
@@ -321,7 +587,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
return nullptr;
func_sig = sig.release();
// Function type is named.
- name = pdb_func->getName();
+ name = MSVCUndecoratedNameParser::DropScope(pdb_func->getName());
} else if (auto pdb_func_sig =
llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) {
func_sig = const_cast<PDBSymbolTypeFunctionSig *>(pdb_func_sig);
@@ -364,9 +630,10 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
type_quals |= clang::Qualifiers::Const;
if (func_sig->isVolatileType())
type_quals |= clang::Qualifiers::Volatile;
+ auto cc = TranslateCallingConvention(func_sig->getCallingConvention());
CompilerType func_sig_ast_type =
m_ast.CreateFunctionType(return_ast_type, arg_list.data(),
- arg_list.size(), is_variadic, type_quals);
+ arg_list.size(), is_variadic, type_quals, cc);
GetDeclarationForSymbol(type, decl);
return std::make_shared<lldb_private::Type>(
@@ -391,7 +658,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
CompilerType element_ast_type = element_type->GetForwardCompilerType();
// If element type is UDT, it needs to be complete.
if (ClangASTContext::IsCXXClassType(element_ast_type) &&
- element_ast_type.GetCompleteType() == false) {
+ !element_ast_type.GetCompleteType()) {
if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) {
ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type);
} else {
@@ -441,6 +708,26 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
if (!pointee_type)
return nullptr;
+ if (pointer_type->isPointerToDataMember() ||
+ pointer_type->isPointerToMemberFunction()) {
+ auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId();
+ auto class_parent_type =
+ m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid);
+ assert(class_parent_type);
+
+ CompilerType pointer_ast_type;
+ pointer_ast_type = ClangASTContext::CreateMemberPointerType(
+ class_parent_type->GetLayoutCompilerType(),
+ pointee_type->GetForwardCompilerType());
+ assert(pointer_ast_type);
+
+ return std::make_shared<lldb_private::Type>(
+ pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(),
+ pointer_type->getLength(), nullptr, LLDB_INVALID_UID,
+ lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type,
+ lldb_private::Type::eResolveStateForward);
+ }
+
CompilerType pointer_ast_type;
pointer_ast_type = pointee_type->GetFullCompilerType();
if (pointer_type->isReference())
@@ -471,11 +758,363 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
return nullptr;
}
+bool PDBASTParser::CompleteTypeFromPDB(
+ lldb_private::CompilerType &compiler_type) {
+ if (GetClangASTImporter().CanImport(compiler_type))
+ return GetClangASTImporter().CompleteType(compiler_type);
+
+ // Remove the type from the forward declarations to avoid
+ // an endless recursion for types like a linked list.
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
+ auto uid_it = m_forward_decl_to_uid.find(record_decl);
+ if (uid_it == m_forward_decl_to_uid.end())
+ return true;
+
+ auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
+ if (!symbol_file)
+ return false;
+
+ std::unique_ptr<PDBSymbol> symbol =
+ symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond());
+ if (!symbol)
+ return false;
+
+ m_forward_decl_to_uid.erase(uid_it);
+
+ ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(),
+ false);
+
+ switch (symbol->getSymTag()) {
+ case PDB_SymType::UDT: {
+ auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(symbol.get());
+ if (!udt)
+ return false;
+
+ return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt);
+ }
+ default:
+ llvm_unreachable("not a forward clang type decl!");
+ }
+}
+
+clang::Decl *
+PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
+ uint32_t sym_id = symbol.getSymIndexId();
+ auto it = m_uid_to_decl.find(sym_id);
+ if (it != m_uid_to_decl.end())
+ return it->second;
+
+ auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
+ if (!symbol_file)
+ return nullptr;
+
+ // First of all, check if the symbol is a member of a class. Resolve the full
+ // class type and return the declaration from the cache if so.
+ auto tag = symbol.getSymTag();
+ if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) {
+ const IPDBSession &session = symbol.getSession();
+ const IPDBRawSymbol &raw = symbol.getRawSymbol();
+
+ auto class_parent_id = raw.getClassParentId();
+ if (std::unique_ptr<PDBSymbol> class_parent =
+ session.getSymbolById(class_parent_id)) {
+ auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id);
+ if (!class_parent_type)
+ return nullptr;
+
+ CompilerType class_parent_ct = class_parent_type->GetFullCompilerType();
+
+ // Look a declaration up in the cache after completing the class
+ clang::Decl *decl = m_uid_to_decl.lookup(sym_id);
+ if (decl)
+ return decl;
+
+ // A declaration was not found in the cache. It means that the symbol
+ // has the class parent, but the class doesn't have the symbol in its
+ // children list.
+ if (auto func = llvm::dyn_cast_or_null<PDBSymbolFunc>(&symbol)) {
+ // Try to find a class child method with the same RVA and use its
+ // declaration if found.
+ if (uint32_t rva = func->getRelativeVirtualAddress()) {
+ if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolFunc>>
+ methods_enum =
+ class_parent->findAllChildren<PDBSymbolFunc>()) {
+ while (std::unique_ptr<PDBSymbolFunc> method =
+ methods_enum->getNext()) {
+ if (method->getRelativeVirtualAddress() == rva) {
+ decl = m_uid_to_decl.lookup(method->getSymIndexId());
+ if (decl)
+ break;
+ }
+ }
+ }
+ }
+
+ // If no class methods with the same RVA were found, then create a new
+ // method. It is possible for template methods.
+ if (!decl)
+ decl = AddRecordMethod(*symbol_file, class_parent_ct, *func);
+ }
+
+ if (decl)
+ m_uid_to_decl[sym_id] = decl;
+
+ return decl;
+ }
+ }
+
+ // If we are here, then the symbol is not belonging to a class and is not
+ // contained in the cache. So create a declaration for it.
+ switch (symbol.getSymTag()) {
+ case PDB_SymType::Data: {
+ auto data = llvm::dyn_cast<PDBSymbolData>(&symbol);
+ assert(data);
+
+ auto decl_context = GetDeclContextContainingSymbol(symbol);
+ assert(decl_context);
+
+ // May be the current context is a class really, but we haven't found
+ // any class parent. This happens e.g. in the case of class static
+ // variables - they has two symbols, one is a child of the class when
+ // another is a child of the exe. So always complete the parent and use
+ // an existing declaration if possible.
+ if (auto parent_decl = llvm::dyn_cast_or_null<clang::TagDecl>(decl_context))
+ m_ast.GetCompleteDecl(parent_decl);
+
+ std::string name = MSVCUndecoratedNameParser::DropScope(data->getName());
+
+ // Check if the current context already contains the symbol with the name.
+ clang::Decl *decl =
+ GetDeclFromContextByName(*m_ast.getASTContext(), *decl_context, name);
+ if (!decl) {
+ auto type = symbol_file->ResolveTypeUID(data->getTypeId());
+ if (!type)
+ return nullptr;
+
+ decl = m_ast.CreateVariableDeclaration(
+ decl_context, name.c_str(),
+ ClangUtil::GetQualType(type->GetLayoutCompilerType()));
+ }
+
+ m_uid_to_decl[sym_id] = decl;
+
+ return decl;
+ }
+ case PDB_SymType::Function: {
+ auto func = llvm::dyn_cast<PDBSymbolFunc>(&symbol);
+ assert(func);
+
+ auto decl_context = GetDeclContextContainingSymbol(symbol);
+ assert(decl_context);
+
+ std::string name = MSVCUndecoratedNameParser::DropScope(func->getName());
+
+ Type *type = symbol_file->ResolveTypeUID(sym_id);
+ if (!type)
+ return nullptr;
+
+ auto storage = func->isStatic() ? clang::StorageClass::SC_Static
+ : clang::StorageClass::SC_None;
+
+ auto decl = m_ast.CreateFunctionDeclaration(
+ decl_context, name.c_str(), type->GetForwardCompilerType(), storage,
+ func->hasInlineAttribute());
+
+ std::vector<clang::ParmVarDecl *> params;
+ if (std::unique_ptr<PDBSymbolTypeFunctionSig> sig = func->getSignature()) {
+ if (std::unique_ptr<ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg>>
+ arg_enum = sig->findAllChildren<PDBSymbolTypeFunctionArg>()) {
+ while (std::unique_ptr<PDBSymbolTypeFunctionArg> arg =
+ arg_enum->getNext()) {
+ Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId());
+ if (!arg_type)
+ continue;
+
+ clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
+ decl, nullptr, arg_type->GetForwardCompilerType(),
+ clang::SC_None);
+ if (param)
+ params.push_back(param);
+ }
+ }
+ }
+ if (params.size())
+ m_ast.SetFunctionParameters(decl, params.data(), params.size());
+
+ m_uid_to_decl[sym_id] = decl;
+
+ return decl;
+ }
+ default: {
+ // It's not a variable and not a function, check if it's a type
+ Type *type = symbol_file->ResolveTypeUID(sym_id);
+ if (!type)
+ return nullptr;
+
+ return m_uid_to_decl.lookup(sym_id);
+ }
+ }
+}
+
+clang::DeclContext *
+PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) {
+ if (symbol.getSymTag() == PDB_SymType::Function) {
+ clang::DeclContext *result =
+ llvm::dyn_cast_or_null<clang::FunctionDecl>(GetDeclForSymbol(symbol));
+
+ if (result)
+ m_decl_context_to_uid[result] = symbol.getSymIndexId();
+
+ return result;
+ }
+
+ auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
+ if (!symbol_file)
+ return nullptr;
+
+ auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId());
+ if (!type)
+ return nullptr;
+
+ clang::DeclContext *result =
+ m_ast.GetDeclContextForType(type->GetForwardCompilerType());
+
+ if (result)
+ m_decl_context_to_uid[result] = symbol.getSymIndexId();
+
+ return result;
+}
+
+clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol(
+ const llvm::pdb::PDBSymbol &symbol) {
+ auto parent = GetClassOrFunctionParent(symbol);
+ while (parent) {
+ if (auto parent_context = GetDeclContextForSymbol(*parent))
+ return parent_context;
+
+ parent = GetClassOrFunctionParent(*parent);
+ }
+
+ // We can't find any class or function parent of the symbol. So analyze
+ // the full symbol name. The symbol may be belonging to a namespace
+ // or function (or even to a class if it's e.g. a static variable symbol).
+
+ // TODO: Make clang to emit full names for variables in namespaces
+ // (as MSVC does)
+
+ std::string name(symbol.getRawSymbol().getName());
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+ if (specs.empty())
+ return m_ast.GetTranslationUnitDecl();
+
+ auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
+ if (!symbol_file)
+ return m_ast.GetTranslationUnitDecl();
+
+ auto global = symbol_file->GetPDBSession().getGlobalScope();
+ if (!global)
+ return m_ast.GetTranslationUnitDecl();
+
+ bool has_type_or_function_parent = false;
+ clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl();
+ for (std::size_t i = 0; i < specs.size() - 1; i++) {
+ // Check if there is a function or a type with the current context's name.
+ if (std::unique_ptr<IPDBEnumSymbols> children_enum = global->findChildren(
+ PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) {
+ while (IPDBEnumChildren<PDBSymbol>::ChildTypePtr child =
+ children_enum->getNext()) {
+ if (clang::DeclContext *child_context =
+ GetDeclContextForSymbol(*child)) {
+ // Note that `GetDeclContextForSymbol' retrieves
+ // a declaration context for functions and types only,
+ // so if we are here then `child_context' is guaranteed
+ // a function or a type declaration context.
+ has_type_or_function_parent = true;
+ curr_context = child_context;
+ }
+ }
+ }
+
+ // If there were no functions or types above then retrieve a namespace with
+ // the current context's name. There can be no namespaces inside a function
+ // or a type. We check it to avoid fake namespaces such as `__l2':
+ // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct'
+ if (!has_type_or_function_parent) {
+ std::string namespace_name = specs[i].GetBaseName();
+ const char *namespace_name_c_str =
+ IsAnonymousNamespaceName(namespace_name) ? nullptr
+ : namespace_name.data();
+ clang::NamespaceDecl *namespace_decl =
+ m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str,
+ curr_context);
+
+ m_parent_to_namespaces[curr_context].insert(namespace_decl);
+ m_namespaces.insert(namespace_decl);
+
+ curr_context = namespace_decl;
+ }
+ }
+
+ return curr_context;
+}
+
+void PDBASTParser::ParseDeclsForDeclContext(
+ const clang::DeclContext *decl_context) {
+ auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
+ if (!symbol_file)
+ return;
+
+ IPDBSession &session = symbol_file->GetPDBSession();
+ auto symbol_up =
+ session.getSymbolById(m_decl_context_to_uid.lookup(decl_context));
+ auto global_up = session.getGlobalScope();
+
+ PDBSymbol *symbol;
+ if (symbol_up)
+ symbol = symbol_up.get();
+ else if (global_up)
+ symbol = global_up.get();
+ else
+ return;
+
+ if (auto children = symbol->findAllChildren())
+ while (auto child = children->getNext())
+ GetDeclForSymbol(*child);
+}
+
+clang::NamespaceDecl *
+PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent,
+ llvm::StringRef name) {
+ NamespacesSet *set;
+ if (parent) {
+ auto pit = m_parent_to_namespaces.find(parent);
+ if (pit == m_parent_to_namespaces.end())
+ return nullptr;
+
+ set = &pit->second;
+ } else {
+ set = &m_namespaces;
+ }
+ assert(set);
+
+ for (clang::NamespaceDecl *namespace_decl : *set)
+ if (namespace_decl->getName().equals(name))
+ return namespace_decl;
+
+ for (clang::NamespaceDecl *namespace_decl : *set)
+ if (namespace_decl->isAnonymousNamespace())
+ return FindNamespaceDecl(namespace_decl, name);
+
+ return nullptr;
+}
+
bool PDBASTParser::AddEnumValue(CompilerType enum_type,
- const PDBSymbolData &enum_value) const {
+ const PDBSymbolData &enum_value) {
Declaration decl;
Variant v = enum_value.getValue();
- std::string name = enum_value.getName();
+ std::string name = MSVCUndecoratedNameParser::DropScope(enum_value.getName());
int64_t raw_value;
switch (v.Type) {
case PDB_VariantType::Int8:
@@ -509,7 +1148,213 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type,
m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType());
uint32_t byte_size = m_ast.getASTContext()->getTypeSize(
ClangUtil::GetQualType(underlying_type));
- return m_ast.AddEnumerationValueToEnumerationType(
- enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(),
- raw_value, byte_size * 8);
+ auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType(
+ enum_type, decl, name.c_str(), raw_value, byte_size * 8);
+ if (!enum_constant_decl)
+ return false;
+
+ m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl;
+
+ return true;
+}
+
+bool PDBASTParser::CompleteTypeFromUDT(
+ lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &compiler_type,
+ llvm::pdb::PDBSymbolTypeUDT &udt) {
+ ClangASTImporter::LayoutInfo layout_info;
+ layout_info.bit_size = udt.getLength() * 8;
+
+ auto nested_enums = udt.findAllChildren<PDBSymbolTypeUDT>();
+ if (nested_enums)
+ while (auto nested = nested_enums->getNext())
+ symbol_file.ResolveTypeUID(nested->getSymIndexId());
+
+ auto bases_enum = udt.findAllChildren<PDBSymbolTypeBaseClass>();
+ if (bases_enum)
+ AddRecordBases(symbol_file, compiler_type,
+ TranslateUdtKind(udt.getUdtKind()), *bases_enum,
+ layout_info);
+
+ auto members_enum = udt.findAllChildren<PDBSymbolData>();
+ if (members_enum)
+ AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info);
+
+ auto methods_enum = udt.findAllChildren<PDBSymbolFunc>();
+ if (methods_enum)
+ AddRecordMethods(symbol_file, compiler_type, *methods_enum);
+
+ m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType());
+ ClangASTContext::BuildIndirectFields(compiler_type);
+ ClangASTContext::CompleteTagDeclarationDefinition(compiler_type);
+
+ clang::CXXRecordDecl *record_decl =
+ m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType());
+ if (!record_decl)
+ return static_cast<bool>(compiler_type);
+
+ GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
+
+ return static_cast<bool>(compiler_type);
+}
+
+void PDBASTParser::AddRecordMembers(
+ lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ PDBDataSymbolEnumerator &members_enum,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info) {
+ while (auto member = members_enum.getNext()) {
+ if (member->isCompilerGenerated())
+ continue;
+
+ auto member_name = member->getName();
+
+ auto member_type = symbol_file.ResolveTypeUID(member->getTypeId());
+ if (!member_type)
+ continue;
+
+ auto member_comp_type = member_type->GetLayoutCompilerType();
+ if (!member_comp_type.GetCompleteType()) {
+ symbol_file.GetObjectFile()->GetModule()->ReportError(
+ ":: Class '%s' has a member '%s' of type '%s' "
+ "which does not have a complete definition.",
+ record_type.GetTypeName().GetCString(), member_name.c_str(),
+ member_comp_type.GetTypeName().GetCString());
+ if (ClangASTContext::StartTagDeclarationDefinition(member_comp_type))
+ ClangASTContext::CompleteTagDeclarationDefinition(member_comp_type);
+ }
+
+ auto access = TranslateMemberAccess(member->getAccess());
+
+ switch (member->getDataKind()) {
+ case PDB_DataKind::Member: {
+ auto location_type = member->getLocationType();
+
+ auto bit_size = member->getLength();
+ if (location_type == PDB_LocType::ThisRel)
+ bit_size *= 8;
+
+ auto decl = ClangASTContext::AddFieldToRecordType(
+ record_type, member_name.c_str(), member_comp_type, access, bit_size);
+ if (!decl)
+ continue;
+
+ m_uid_to_decl[member->getSymIndexId()] = decl;
+
+ auto offset = member->getOffset() * 8;
+ if (location_type == PDB_LocType::BitField)
+ offset += member->getBitPosition();
+
+ layout_info.field_offsets.insert(std::make_pair(decl, offset));
+
+ break;
+ }
+ case PDB_DataKind::StaticMember: {
+ auto decl = ClangASTContext::AddVariableToRecordType(
+ record_type, member_name.c_str(), member_comp_type, access);
+ if (!decl)
+ continue;
+
+ m_uid_to_decl[member->getSymIndexId()] = decl;
+
+ break;
+ }
+ default:
+ llvm_unreachable("unsupported PDB data kind");
+ }
+ }
+}
+
+void PDBASTParser::AddRecordBases(
+ lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type, int record_kind,
+ PDBBaseClassSymbolEnumerator &bases_enum,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info) const {
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> base_classes;
+
+ while (auto base = bases_enum.getNext()) {
+ auto base_type = symbol_file.ResolveTypeUID(base->getTypeId());
+ if (!base_type)
+ continue;
+
+ auto base_comp_type = base_type->GetFullCompilerType();
+ if (!base_comp_type.GetCompleteType()) {
+ symbol_file.GetObjectFile()->GetModule()->ReportError(
+ ":: Class '%s' has a base class '%s' "
+ "which does not have a complete definition.",
+ record_type.GetTypeName().GetCString(),
+ base_comp_type.GetTypeName().GetCString());
+ if (ClangASTContext::StartTagDeclarationDefinition(base_comp_type))
+ ClangASTContext::CompleteTagDeclarationDefinition(base_comp_type);
+ }
+
+ auto access = TranslateMemberAccess(base->getAccess());
+
+ auto is_virtual = base->isVirtualBaseClass();
+
+ std::unique_ptr<clang::CXXBaseSpecifier> base_spec =
+ m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(),
+ access, is_virtual,
+ record_kind == clang::TTK_Class);
+ lldbassert(base_spec);
+
+ base_classes.push_back(std::move(base_spec));
+
+ if (is_virtual)
+ continue;
+
+ auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType());
+ if (!decl)
+ continue;
+
+ auto offset = clang::CharUnits::fromQuantity(base->getOffset());
+ layout_info.base_offsets.insert(std::make_pair(decl, offset));
+ }
+
+ m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(),
+ std::move(base_classes));
+}
+
+void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ PDBFuncSymbolEnumerator &methods_enum) {
+ while (std::unique_ptr<PDBSymbolFunc> method = methods_enum.getNext())
+ if (clang::CXXMethodDecl *decl =
+ AddRecordMethod(symbol_file, record_type, *method))
+ m_uid_to_decl[method->getSymIndexId()] = decl;
+}
+
+clang::CXXMethodDecl *
+PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ const llvm::pdb::PDBSymbolFunc &method) const {
+ std::string name = MSVCUndecoratedNameParser::DropScope(method.getName());
+
+ Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId());
+ // MSVC specific __vecDelDtor.
+ if (!method_type)
+ return nullptr;
+
+ CompilerType method_comp_type = method_type->GetFullCompilerType();
+ if (!method_comp_type.GetCompleteType()) {
+ symbol_file.GetObjectFile()->GetModule()->ReportError(
+ ":: Class '%s' has a method '%s' whose type cannot be completed.",
+ record_type.GetTypeName().GetCString(),
+ method_comp_type.GetTypeName().GetCString());
+ if (ClangASTContext::StartTagDeclarationDefinition(method_comp_type))
+ ClangASTContext::CompleteTagDeclarationDefinition(method_comp_type);
+ }
+
+ AccessType access = TranslateMemberAccess(method.getAccess());
+ if (access == eAccessNone)
+ access = eAccessPublic;
+
+ // TODO: get mangled name for the method.
+ return m_ast.AddMethodToCXXRecordType(
+ record_type.GetOpaqueQualType(), name.c_str(),
+ /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(),
+ method.isStatic(), method.hasInlineAttribute(),
+ /*is_explicit*/ false, // FIXME: Need this field in CodeView.
+ /*is_attr_used*/ false,
+ /*is_artificial*/ method.isCompilerGenerated());
}
diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
index d1ac138b8115..02353870ab60 100644
--- a/source/Plugins/SymbolFile/PDB/PDBASTParser.h
+++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.h
@@ -14,6 +14,8 @@
#include "lldb/Symbol/ClangASTImporter.h"
+class SymbolFilePDB;
+
namespace clang {
class CharUnits;
class CXXRecordDecl;
@@ -28,9 +30,14 @@ class CompilerType;
namespace llvm {
namespace pdb {
+template <typename ChildType> class ConcreteSymbolEnumerator;
+
class PDBSymbol;
class PDBSymbolData;
+class PDBSymbolFunc;
+class PDBSymbolTypeBaseClass;
class PDBSymbolTypeBuiltin;
+class PDBSymbolTypeUDT;
} // namespace pdb
} // namespace llvm
@@ -40,13 +47,71 @@ public:
~PDBASTParser();
lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type);
+ bool CompleteTypeFromPDB(lldb_private::CompilerType &compiler_type);
+
+ clang::Decl *GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol);
+
+ clang::DeclContext *
+ GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol);
+ clang::DeclContext *
+ GetDeclContextContainingSymbol(const llvm::pdb::PDBSymbol &symbol);
+
+ void ParseDeclsForDeclContext(const clang::DeclContext *decl_context);
+
+ clang::NamespaceDecl *FindNamespaceDecl(const clang::DeclContext *parent,
+ llvm::StringRef name);
+
+ lldb_private::ClangASTImporter &GetClangASTImporter() {
+ return m_ast_importer;
+ }
private:
+ typedef llvm::DenseMap<clang::CXXRecordDecl *, lldb::user_id_t>
+ CXXRecordDeclToUidMap;
+ typedef llvm::DenseMap<lldb::user_id_t, clang::Decl *> UidToDeclMap;
+ typedef std::set<clang::NamespaceDecl *> NamespacesSet;
+ typedef llvm::DenseMap<clang::DeclContext *, NamespacesSet>
+ ParentToNamespacesMap;
+ typedef llvm::DenseMap<clang::DeclContext *, lldb::user_id_t>
+ DeclContextToUidMap;
+ typedef llvm::pdb::ConcreteSymbolEnumerator<llvm::pdb::PDBSymbolData>
+ PDBDataSymbolEnumerator;
+ typedef llvm::pdb::ConcreteSymbolEnumerator<llvm::pdb::PDBSymbolTypeBaseClass>
+ PDBBaseClassSymbolEnumerator;
+ typedef llvm::pdb::ConcreteSymbolEnumerator<llvm::pdb::PDBSymbolFunc>
+ PDBFuncSymbolEnumerator;
+
bool AddEnumValue(lldb_private::CompilerType enum_type,
- const llvm::pdb::PDBSymbolData &data) const;
+ const llvm::pdb::PDBSymbolData &data);
+ bool CompleteTypeFromUDT(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &compiler_type,
+ llvm::pdb::PDBSymbolTypeUDT &udt);
+ void
+ AddRecordMembers(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ PDBDataSymbolEnumerator &members_enum,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
+ void
+ AddRecordBases(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type, int record_kind,
+ PDBBaseClassSymbolEnumerator &bases_enum,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info) const;
+ void AddRecordMethods(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ PDBFuncSymbolEnumerator &methods_enum);
+ clang::CXXMethodDecl *
+ AddRecordMethod(lldb_private::SymbolFile &symbol_file,
+ lldb_private::CompilerType &record_type,
+ const llvm::pdb::PDBSymbolFunc &method) const;
lldb_private::ClangASTContext &m_ast;
lldb_private::ClangASTImporter m_ast_importer;
+
+ CXXRecordDeclToUidMap m_forward_decl_to_uid;
+ UidToDeclMap m_uid_to_decl;
+ ParentToNamespacesMap m_parent_to_namespaces;
+ NamespacesSet m_namespaces;
+ DeclContextToUidMap m_decl_context_to_uid;
};
#endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H
diff --git a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
index 69ef70cc508c..9f398ef9b047 100644
--- a/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ b/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -26,51 +26,51 @@ using namespace llvm::pdb;
namespace {
const uint32_t g_code_view_to_lldb_registers_x86[] = {
- LLDB_INVALID_REGNUM, // CVRegNONE
- lldb_al_i386, // CVRegAL
- lldb_cl_i386, // CVRegCL
- lldb_dl_i386, // CVRegDL
- lldb_bl_i386, // CVRegBL
- lldb_ah_i386, // CVRegAH
- lldb_ch_i386, // CVRegCH
- lldb_dh_i386, // CVRegDH
- lldb_bh_i386, // CVRegBH
- lldb_ax_i386, // CVRegAX
- lldb_cx_i386, // CVRegCX
- lldb_dx_i386, // CVRegDX
- lldb_bx_i386, // CVRegBX
- lldb_sp_i386, // CVRegSP
- lldb_bp_i386, // CVRegBP
- lldb_si_i386, // CVRegSI
- lldb_di_i386, // CVRegDI
- lldb_eax_i386, // CVRegEAX
- lldb_ecx_i386, // CVRegECX
- lldb_edx_i386, // CVRegEDX
- lldb_ebx_i386, // CVRegEBX
- lldb_esp_i386, // CVRegESP
- lldb_ebp_i386, // CVRegEBP
- lldb_esi_i386, // CVRegESI
- lldb_edi_i386, // CVRegEDI
- lldb_es_i386, // CVRegES
- lldb_cs_i386, // CVRegCS
- lldb_ss_i386, // CVRegSS
- lldb_ds_i386, // CVRegDS
- lldb_fs_i386, // CVRegFS
- lldb_gs_i386, // CVRegGS
- LLDB_INVALID_REGNUM, // CVRegIP
- LLDB_INVALID_REGNUM, // CVRegFLAGS
- lldb_eip_i386, // CVRegEIP
- lldb_eflags_i386, // CVRegEFLAGS
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_i386, // AL
+ lldb_cl_i386, // CL
+ lldb_dl_i386, // DL
+ lldb_bl_i386, // BL
+ lldb_ah_i386, // AH
+ lldb_ch_i386, // CH
+ lldb_dh_i386, // DH
+ lldb_bh_i386, // BH
+ lldb_ax_i386, // AX
+ lldb_cx_i386, // CX
+ lldb_dx_i386, // DX
+ lldb_bx_i386, // BX
+ lldb_sp_i386, // SP
+ lldb_bp_i386, // BP
+ lldb_si_i386, // SI
+ lldb_di_i386, // DI
+ lldb_eax_i386, // EAX
+ lldb_ecx_i386, // ECX
+ lldb_edx_i386, // EDX
+ lldb_ebx_i386, // EBX
+ lldb_esp_i386, // ESP
+ lldb_ebp_i386, // EBP
+ lldb_esi_i386, // ESI
+ lldb_edi_i386, // EDI
+ lldb_es_i386, // ES
+ lldb_cs_i386, // CS
+ lldb_ss_i386, // SS
+ lldb_ds_i386, // DS
+ lldb_fs_i386, // FS
+ lldb_gs_i386, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ lldb_eip_i386, // EIP
+ lldb_eflags_i386, // EFLAGS
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegTEMP
- LLDB_INVALID_REGNUM, // CVRegTEMPH
- LLDB_INVALID_REGNUM, // CVRegQUOTE
- LLDB_INVALID_REGNUM, // CVRegPCDR3
- LLDB_INVALID_REGNUM, // CVRegPCDR4
- LLDB_INVALID_REGNUM, // CVRegPCDR5
- LLDB_INVALID_REGNUM, // CVRegPCDR6
- LLDB_INVALID_REGNUM, // CVRegPCDR7
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
@@ -82,123 +82,123 @@ const uint32_t g_code_view_to_lldb_registers_x86[] = {
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegCR0
- LLDB_INVALID_REGNUM, // CVRegCR1
- LLDB_INVALID_REGNUM, // CVRegCR2
- LLDB_INVALID_REGNUM, // CVRegCR3
- LLDB_INVALID_REGNUM, // CVRegCR4
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_i386, // CVRegDR0
- lldb_dr1_i386, // CVRegDR1
- lldb_dr2_i386, // CVRegDR2
- lldb_dr3_i386, // CVRegDR3
- lldb_dr4_i386, // CVRegDR4
- lldb_dr5_i386, // CVRegDR5
- lldb_dr6_i386, // CVRegDR6
- lldb_dr7_i386, // CVRegDR7
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegGDTR
- LLDB_INVALID_REGNUM, // CVRegGDTL
- LLDB_INVALID_REGNUM, // CVRegIDTR
- LLDB_INVALID_REGNUM, // CVRegIDTL
- LLDB_INVALID_REGNUM, // CVRegLDTR
- LLDB_INVALID_REGNUM, // CVRegTR
- LLDB_INVALID_REGNUM, // CVRegPSEUDO1
- LLDB_INVALID_REGNUM, // CVRegPSEUDO2
- LLDB_INVALID_REGNUM, // CVRegPSEUDO3
- LLDB_INVALID_REGNUM, // CVRegPSEUDO4
- LLDB_INVALID_REGNUM, // CVRegPSEUDO5
- LLDB_INVALID_REGNUM, // CVRegPSEUDO6
- LLDB_INVALID_REGNUM, // CVRegPSEUDO7
- LLDB_INVALID_REGNUM, // CVRegPSEUDO8
- LLDB_INVALID_REGNUM, // CVRegPSEUDO9
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_i386, // CVRegST0
- lldb_st1_i386, // CVRegST1
- lldb_st2_i386, // CVRegST2
- lldb_st3_i386, // CVRegST3
- lldb_st4_i386, // CVRegST4
- lldb_st5_i386, // CVRegST5
- lldb_st6_i386, // CVRegST6
- lldb_st7_i386, // CVRegST7
- LLDB_INVALID_REGNUM, // CVRegCTRL
- LLDB_INVALID_REGNUM, // CVRegSTAT
- LLDB_INVALID_REGNUM, // CVRegTAG
- LLDB_INVALID_REGNUM, // CVRegFPIP
- LLDB_INVALID_REGNUM, // CVRegFPCS
- LLDB_INVALID_REGNUM, // CVRegFPDO
- LLDB_INVALID_REGNUM, // CVRegFPDS
- LLDB_INVALID_REGNUM, // CVRegISEM
- LLDB_INVALID_REGNUM, // CVRegFPEIP
- LLDB_INVALID_REGNUM, // CVRegFPEDO
- lldb_mm0_i386, // CVRegMM0
- lldb_mm1_i386, // CVRegMM1
- lldb_mm2_i386, // CVRegMM2
- lldb_mm3_i386, // CVRegMM3
- lldb_mm4_i386, // CVRegMM4
- lldb_mm5_i386, // CVRegMM5
- lldb_mm6_i386, // CVRegMM6
- lldb_mm7_i386, // CVRegMM7
- lldb_xmm0_i386, // CVRegXMM0
- lldb_xmm1_i386, // CVRegXMM1
- lldb_xmm2_i386, // CVRegXMM2
- lldb_xmm3_i386, // CVRegXMM3
- lldb_xmm4_i386, // CVRegXMM4
- lldb_xmm5_i386, // CVRegXMM5
- lldb_xmm6_i386, // CVRegXMM6
- lldb_xmm7_i386 // CVRegXMM7
+ lldb_dr0_i386, // DR0
+ lldb_dr1_i386, // DR1
+ lldb_dr2_i386, // DR2
+ lldb_dr3_i386, // DR3
+ lldb_dr4_i386, // DR4
+ lldb_dr5_i386, // DR5
+ lldb_dr6_i386, // DR6
+ lldb_dr7_i386, // DR7
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_st0_i386, // ST0
+ lldb_st1_i386, // ST1
+ lldb_st2_i386, // ST2
+ lldb_st3_i386, // ST3
+ lldb_st4_i386, // ST4
+ lldb_st5_i386, // ST5
+ lldb_st6_i386, // ST6
+ lldb_st7_i386, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_i386, // MM0
+ lldb_mm1_i386, // MM1
+ lldb_mm2_i386, // MM2
+ lldb_mm3_i386, // MM3
+ lldb_mm4_i386, // MM4
+ lldb_mm5_i386, // MM5
+ lldb_mm6_i386, // MM6
+ lldb_mm7_i386, // MM7
+ lldb_xmm0_i386, // XMM0
+ lldb_xmm1_i386, // XMM1
+ lldb_xmm2_i386, // XMM2
+ lldb_xmm3_i386, // XMM3
+ lldb_xmm4_i386, // XMM4
+ lldb_xmm5_i386, // XMM5
+ lldb_xmm6_i386, // XMM6
+ lldb_xmm7_i386 // XMM7
};
const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
- LLDB_INVALID_REGNUM, // CVRegNONE
- lldb_al_x86_64, // CVRegAL
- lldb_cl_x86_64, // CVRegCL
- lldb_dl_x86_64, // CVRegDL
- lldb_bl_x86_64, // CVRegBL
- lldb_ah_x86_64, // CVRegAH
- lldb_ch_x86_64, // CVRegCH
- lldb_dh_x86_64, // CVRegDH
- lldb_bh_x86_64, // CVRegBH
- lldb_ax_x86_64, // CVRegAX
- lldb_cx_x86_64, // CVRegCX
- lldb_dx_x86_64, // CVRegDX
- lldb_bx_x86_64, // CVRegBX
- lldb_sp_x86_64, // CVRegSP
- lldb_bp_x86_64, // CVRegBP
- lldb_si_x86_64, // CVRegSI
- lldb_di_x86_64, // CVRegDI
- lldb_eax_x86_64, // CVRegEAX
- lldb_ecx_x86_64, // CVRegECX
- lldb_edx_x86_64, // CVRegEDX
- lldb_ebx_x86_64, // CVRegEBX
- lldb_esp_x86_64, // CVRegESP
- lldb_ebp_x86_64, // CVRegEBP
- lldb_esi_x86_64, // CVRegESI
- lldb_edi_x86_64, // CVRegEDI
- lldb_es_x86_64, // CVRegES
- lldb_cs_x86_64, // CVRegCS
- lldb_ss_x86_64, // CVRegSS
- lldb_ds_x86_64, // CVRegDS
- lldb_fs_x86_64, // CVRegFS
- lldb_gs_x86_64, // CVRegGS
- LLDB_INVALID_REGNUM, // CVRegIP
- LLDB_INVALID_REGNUM, // CVRegFLAGS
- LLDB_INVALID_REGNUM, // CVRegEIP
- LLDB_INVALID_REGNUM, // CVRegEFLAGS
+ LLDB_INVALID_REGNUM, // NONE
+ lldb_al_x86_64, // AL
+ lldb_cl_x86_64, // CL
+ lldb_dl_x86_64, // DL
+ lldb_bl_x86_64, // BL
+ lldb_ah_x86_64, // AH
+ lldb_ch_x86_64, // CH
+ lldb_dh_x86_64, // DH
+ lldb_bh_x86_64, // BH
+ lldb_ax_x86_64, // AX
+ lldb_cx_x86_64, // CX
+ lldb_dx_x86_64, // DX
+ lldb_bx_x86_64, // BX
+ lldb_sp_x86_64, // SP
+ lldb_bp_x86_64, // BP
+ lldb_si_x86_64, // SI
+ lldb_di_x86_64, // DI
+ lldb_eax_x86_64, // EAX
+ lldb_ecx_x86_64, // ECX
+ lldb_edx_x86_64, // EDX
+ lldb_ebx_x86_64, // EBX
+ lldb_esp_x86_64, // ESP
+ lldb_ebp_x86_64, // EBP
+ lldb_esi_x86_64, // ESI
+ lldb_edi_x86_64, // EDI
+ lldb_es_x86_64, // ES
+ lldb_cs_x86_64, // CS
+ lldb_ss_x86_64, // SS
+ lldb_ds_x86_64, // DS
+ lldb_fs_x86_64, // FS
+ lldb_gs_x86_64, // GS
+ LLDB_INVALID_REGNUM, // IP
+ LLDB_INVALID_REGNUM, // FLAGS
+ LLDB_INVALID_REGNUM, // EIP
+ LLDB_INVALID_REGNUM, // EFLAGS
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegTEMP
- LLDB_INVALID_REGNUM, // CVRegTEMPH
- LLDB_INVALID_REGNUM, // CVRegQUOTE
- LLDB_INVALID_REGNUM, // CVRegPCDR3
- LLDB_INVALID_REGNUM, // CVRegPCDR4
- LLDB_INVALID_REGNUM, // CVRegPCDR5
- LLDB_INVALID_REGNUM, // CVRegPCDR6
- LLDB_INVALID_REGNUM, // CVRegPCDR7
+ LLDB_INVALID_REGNUM, // TEMP
+ LLDB_INVALID_REGNUM, // TEMPH
+ LLDB_INVALID_REGNUM, // QUOTE
+ LLDB_INVALID_REGNUM, // PCDR3
+ LLDB_INVALID_REGNUM, // PCDR4
+ LLDB_INVALID_REGNUM, // PCDR5
+ LLDB_INVALID_REGNUM, // PCDR6
+ LLDB_INVALID_REGNUM, // PCDR7
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
@@ -210,75 +210,75 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegCR0
- LLDB_INVALID_REGNUM, // CVRegCR1
- LLDB_INVALID_REGNUM, // CVRegCR2
- LLDB_INVALID_REGNUM, // CVRegCR3
- LLDB_INVALID_REGNUM, // CVRegCR4
+ LLDB_INVALID_REGNUM, // CR0
+ LLDB_INVALID_REGNUM, // CR1
+ LLDB_INVALID_REGNUM, // CR2
+ LLDB_INVALID_REGNUM, // CR3
+ LLDB_INVALID_REGNUM, // CR4
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_dr0_x86_64, // CVRegDR0
- lldb_dr1_x86_64, // CVRegDR1
- lldb_dr2_x86_64, // CVRegDR2
- lldb_dr3_x86_64, // CVRegDR3
- lldb_dr4_x86_64, // CVRegDR4
- lldb_dr5_x86_64, // CVRegDR5
- lldb_dr6_x86_64, // CVRegDR6
- lldb_dr7_x86_64, // CVRegDR7
+ lldb_dr0_x86_64, // DR0
+ lldb_dr1_x86_64, // DR1
+ lldb_dr2_x86_64, // DR2
+ lldb_dr3_x86_64, // DR3
+ lldb_dr4_x86_64, // DR4
+ lldb_dr5_x86_64, // DR5
+ lldb_dr6_x86_64, // DR6
+ lldb_dr7_x86_64, // DR7
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegGDTR
- LLDB_INVALID_REGNUM, // CVRegGDTL
- LLDB_INVALID_REGNUM, // CVRegIDTR
- LLDB_INVALID_REGNUM, // CVRegIDTL
- LLDB_INVALID_REGNUM, // CVRegLDTR
- LLDB_INVALID_REGNUM, // CVRegTR
- LLDB_INVALID_REGNUM, // CVRegPSEUDO1
- LLDB_INVALID_REGNUM, // CVRegPSEUDO2
- LLDB_INVALID_REGNUM, // CVRegPSEUDO3
- LLDB_INVALID_REGNUM, // CVRegPSEUDO4
- LLDB_INVALID_REGNUM, // CVRegPSEUDO5
- LLDB_INVALID_REGNUM, // CVRegPSEUDO6
- LLDB_INVALID_REGNUM, // CVRegPSEUDO7
- LLDB_INVALID_REGNUM, // CVRegPSEUDO8
- LLDB_INVALID_REGNUM, // CVRegPSEUDO9
+ LLDB_INVALID_REGNUM, // GDTR
+ LLDB_INVALID_REGNUM, // GDTL
+ LLDB_INVALID_REGNUM, // IDTR
+ LLDB_INVALID_REGNUM, // IDTL
+ LLDB_INVALID_REGNUM, // LDTR
+ LLDB_INVALID_REGNUM, // TR
+ LLDB_INVALID_REGNUM, // PSEUDO1
+ LLDB_INVALID_REGNUM, // PSEUDO2
+ LLDB_INVALID_REGNUM, // PSEUDO3
+ LLDB_INVALID_REGNUM, // PSEUDO4
+ LLDB_INVALID_REGNUM, // PSEUDO5
+ LLDB_INVALID_REGNUM, // PSEUDO6
+ LLDB_INVALID_REGNUM, // PSEUDO7
+ LLDB_INVALID_REGNUM, // PSEUDO8
+ LLDB_INVALID_REGNUM, // PSEUDO9
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_st0_x86_64, // CVRegST0
- lldb_st1_x86_64, // CVRegST1
- lldb_st2_x86_64, // CVRegST2
- lldb_st3_x86_64, // CVRegST3
- lldb_st4_x86_64, // CVRegST4
- lldb_st5_x86_64, // CVRegST5
- lldb_st6_x86_64, // CVRegST6
- lldb_st7_x86_64, // CVRegST7
- LLDB_INVALID_REGNUM, // CVRegCTRL
- LLDB_INVALID_REGNUM, // CVRegSTAT
- LLDB_INVALID_REGNUM, // CVRegTAG
- LLDB_INVALID_REGNUM, // CVRegFPIP
- LLDB_INVALID_REGNUM, // CVRegFPCS
- LLDB_INVALID_REGNUM, // CVRegFPDO
- LLDB_INVALID_REGNUM, // CVRegFPDS
- LLDB_INVALID_REGNUM, // CVRegISEM
- LLDB_INVALID_REGNUM, // CVRegFPEIP
- LLDB_INVALID_REGNUM, // CVRegFPEDO
- lldb_mm0_x86_64, // CVRegMM0
- lldb_mm1_x86_64, // CVRegMM1
- lldb_mm2_x86_64, // CVRegMM2
- lldb_mm3_x86_64, // CVRegMM3
- lldb_mm4_x86_64, // CVRegMM4
- lldb_mm5_x86_64, // CVRegMM5
- lldb_mm6_x86_64, // CVRegMM6
- lldb_mm7_x86_64, // CVRegMM7
- lldb_xmm0_x86_64, // CVRegXMM0
- lldb_xmm1_x86_64, // CVRegXMM1
- lldb_xmm2_x86_64, // CVRegXMM2
- lldb_xmm3_x86_64, // CVRegXMM3
- lldb_xmm4_x86_64, // CVRegXMM4
- lldb_xmm5_x86_64, // CVRegXMM5
- lldb_xmm6_x86_64, // CVRegXMM6
- lldb_xmm7_x86_64, // CVRegXMM7
+ lldb_st0_x86_64, // ST0
+ lldb_st1_x86_64, // ST1
+ lldb_st2_x86_64, // ST2
+ lldb_st3_x86_64, // ST3
+ lldb_st4_x86_64, // ST4
+ lldb_st5_x86_64, // ST5
+ lldb_st6_x86_64, // ST6
+ lldb_st7_x86_64, // ST7
+ LLDB_INVALID_REGNUM, // CTRL
+ LLDB_INVALID_REGNUM, // STAT
+ LLDB_INVALID_REGNUM, // TAG
+ LLDB_INVALID_REGNUM, // FPIP
+ LLDB_INVALID_REGNUM, // FPCS
+ LLDB_INVALID_REGNUM, // FPDO
+ LLDB_INVALID_REGNUM, // FPDS
+ LLDB_INVALID_REGNUM, // ISEM
+ LLDB_INVALID_REGNUM, // FPEIP
+ LLDB_INVALID_REGNUM, // FPEDO
+ lldb_mm0_x86_64, // MM0
+ lldb_mm1_x86_64, // MM1
+ lldb_mm2_x86_64, // MM2
+ lldb_mm3_x86_64, // MM3
+ lldb_mm4_x86_64, // MM4
+ lldb_mm5_x86_64, // MM5
+ lldb_mm6_x86_64, // MM6
+ lldb_mm7_x86_64, // MM7
+ lldb_xmm0_x86_64, // XMM0
+ lldb_xmm1_x86_64, // XMM1
+ lldb_xmm2_x86_64, // XMM2
+ lldb_xmm3_x86_64, // XMM3
+ lldb_xmm4_x86_64, // XMM4
+ lldb_xmm5_x86_64, // XMM5
+ lldb_xmm6_x86_64, // XMM6
+ lldb_xmm7_x86_64, // XMM7
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
@@ -296,51 +296,51 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM,
- lldb_mxcsr_x86_64, // CVRegMXCSR
- LLDB_INVALID_REGNUM, // CVRegEDXEAX
+ lldb_mxcsr_x86_64, // MXCSR
+ LLDB_INVALID_REGNUM, // EDXEAX
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, // CVRegEMM0L
- LLDB_INVALID_REGNUM, // CVRegEMM1L
- LLDB_INVALID_REGNUM, // CVRegEMM2L
- LLDB_INVALID_REGNUM, // CVRegEMM3L
- LLDB_INVALID_REGNUM, // CVRegEMM4L
- LLDB_INVALID_REGNUM, // CVRegEMM5L
- LLDB_INVALID_REGNUM, // CVRegEMM6L
- LLDB_INVALID_REGNUM, // CVRegEMM7L
- LLDB_INVALID_REGNUM, // CVRegEMM0H
- LLDB_INVALID_REGNUM, // CVRegEMM1H
- LLDB_INVALID_REGNUM, // CVRegEMM2H
- LLDB_INVALID_REGNUM, // CVRegEMM3H
- LLDB_INVALID_REGNUM, // CVRegEMM4H
- LLDB_INVALID_REGNUM, // CVRegEMM5H
- LLDB_INVALID_REGNUM, // CVRegEMM6H
- LLDB_INVALID_REGNUM, // CVRegEMM7H
- LLDB_INVALID_REGNUM, // CVRegMM00
- LLDB_INVALID_REGNUM, // CVRegMM01
- LLDB_INVALID_REGNUM, // CVRegMM10
- LLDB_INVALID_REGNUM, // CVRegMM11
- LLDB_INVALID_REGNUM, // CVRegMM20
- LLDB_INVALID_REGNUM, // CVRegMM21
- LLDB_INVALID_REGNUM, // CVRegMM30
- LLDB_INVALID_REGNUM, // CVRegMM31
- LLDB_INVALID_REGNUM, // CVRegMM40
- LLDB_INVALID_REGNUM, // CVRegMM41
- LLDB_INVALID_REGNUM, // CVRegMM50
- LLDB_INVALID_REGNUM, // CVRegMM51
- LLDB_INVALID_REGNUM, // CVRegMM60
- LLDB_INVALID_REGNUM, // CVRegMM61
- LLDB_INVALID_REGNUM, // CVRegMM70
- LLDB_INVALID_REGNUM, // CVRegMM71
- lldb_xmm8_x86_64, // CVRegXMM8
- lldb_xmm9_x86_64, // CVRegXMM9
- lldb_xmm10_x86_64, // CVRegXMM10
- lldb_xmm11_x86_64, // CVRegXMM11
- lldb_xmm12_x86_64, // CVRegXMM12
- lldb_xmm13_x86_64, // CVRegXMM13
- lldb_xmm14_x86_64, // CVRegXMM14
- lldb_xmm15_x86_64, // CVRegXMM15
+ LLDB_INVALID_REGNUM, // EMM0L
+ LLDB_INVALID_REGNUM, // EMM1L
+ LLDB_INVALID_REGNUM, // EMM2L
+ LLDB_INVALID_REGNUM, // EMM3L
+ LLDB_INVALID_REGNUM, // EMM4L
+ LLDB_INVALID_REGNUM, // EMM5L
+ LLDB_INVALID_REGNUM, // EMM6L
+ LLDB_INVALID_REGNUM, // EMM7L
+ LLDB_INVALID_REGNUM, // EMM0H
+ LLDB_INVALID_REGNUM, // EMM1H
+ LLDB_INVALID_REGNUM, // EMM2H
+ LLDB_INVALID_REGNUM, // EMM3H
+ LLDB_INVALID_REGNUM, // EMM4H
+ LLDB_INVALID_REGNUM, // EMM5H
+ LLDB_INVALID_REGNUM, // EMM6H
+ LLDB_INVALID_REGNUM, // EMM7H
+ LLDB_INVALID_REGNUM, // MM00
+ LLDB_INVALID_REGNUM, // MM01
+ LLDB_INVALID_REGNUM, // MM10
+ LLDB_INVALID_REGNUM, // MM11
+ LLDB_INVALID_REGNUM, // MM20
+ LLDB_INVALID_REGNUM, // MM21
+ LLDB_INVALID_REGNUM, // MM30
+ LLDB_INVALID_REGNUM, // MM31
+ LLDB_INVALID_REGNUM, // MM40
+ LLDB_INVALID_REGNUM, // MM41
+ LLDB_INVALID_REGNUM, // MM50
+ LLDB_INVALID_REGNUM, // MM51
+ LLDB_INVALID_REGNUM, // MM60
+ LLDB_INVALID_REGNUM, // MM61
+ LLDB_INVALID_REGNUM, // MM70
+ LLDB_INVALID_REGNUM, // MM71
+ lldb_xmm8_x86_64, // XMM8
+ lldb_xmm9_x86_64, // XMM9
+ lldb_xmm10_x86_64, // XMM10
+ lldb_xmm11_x86_64, // XMM11
+ lldb_xmm12_x86_64, // XMM12
+ lldb_xmm13_x86_64, // XMM13
+ lldb_xmm14_x86_64, // XMM14
+ lldb_xmm15_x86_64, // XMM15
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
@@ -363,73 +363,73 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
LLDB_INVALID_REGNUM,
- lldb_sil_x86_64, // CVRegSIL
- lldb_dil_x86_64, // CVRegDIL
- lldb_bpl_x86_64, // CVRegBPL
- lldb_spl_x86_64, // CVRegSPL
- lldb_rax_x86_64, // CVRegRAX
- lldb_rbx_x86_64, // CVRegRBX
- lldb_rcx_x86_64, // CVRegRCX
- lldb_rdx_x86_64, // CVRegRDX
- lldb_rsi_x86_64, // CVRegRSI
- lldb_rdi_x86_64, // CVRegRDI
- lldb_rbp_x86_64, // CVRegRBP
- lldb_rsp_x86_64, // CVRegRSP
- lldb_r8_x86_64, // CVRegR8
- lldb_r9_x86_64, // CVRegR9
- lldb_r10_x86_64, // CVRegR10
- lldb_r11_x86_64, // CVRegR11
- lldb_r12_x86_64, // CVRegR12
- lldb_r13_x86_64, // CVRegR13
- lldb_r14_x86_64, // CVRegR14
- lldb_r15_x86_64, // CVRegR15
- lldb_r8l_x86_64, // CVRegR8B
- lldb_r9l_x86_64, // CVRegR9B
- lldb_r10l_x86_64, // CVRegR10B
- lldb_r11l_x86_64, // CVRegR11B
- lldb_r12l_x86_64, // CVRegR12B
- lldb_r13l_x86_64, // CVRegR13B
- lldb_r14l_x86_64, // CVRegR14B
- lldb_r15l_x86_64, // CVRegR15B
- lldb_r8w_x86_64, // CVRegR8W
- lldb_r9w_x86_64, // CVRegR9W
- lldb_r10w_x86_64, // CVRegR10W
- lldb_r11w_x86_64, // CVRegR11W
- lldb_r12w_x86_64, // CVRegR12W
- lldb_r13w_x86_64, // CVRegR13W
- lldb_r14w_x86_64, // CVRegR14W
- lldb_r15w_x86_64, // CVRegR15W
- lldb_r8d_x86_64, // CVRegR8D
- lldb_r9d_x86_64, // CVRegR9D
- lldb_r10d_x86_64, // CVRegR10D
- lldb_r11d_x86_64, // CVRegR11D
- lldb_r12d_x86_64, // CVRegR12D
- lldb_r13d_x86_64, // CVRegR13D
- lldb_r14d_x86_64, // CVRegR14D
- lldb_r15d_x86_64, // CVRegR15D
- lldb_ymm0_x86_64, // CVRegAMD64_YMM0
- lldb_ymm1_x86_64, // CVRegAMD64_YMM1
- lldb_ymm2_x86_64, // CVRegAMD64_YMM2
- lldb_ymm3_x86_64, // CVRegAMD64_YMM3
- lldb_ymm4_x86_64, // CVRegAMD64_YMM4
- lldb_ymm5_x86_64, // CVRegAMD64_YMM5
- lldb_ymm6_x86_64, // CVRegAMD64_YMM6
- lldb_ymm7_x86_64, // CVRegAMD64_YMM7
- lldb_ymm8_x86_64, // CVRegAMD64_YMM8
- lldb_ymm9_x86_64, // CVRegAMD64_YMM9
- lldb_ymm10_x86_64, // CVRegAMD64_YMM10
- lldb_ymm11_x86_64, // CVRegAMD64_YMM11
- lldb_ymm12_x86_64, // CVRegAMD64_YMM12
- lldb_ymm13_x86_64, // CVRegAMD64_YMM13
- lldb_ymm14_x86_64, // CVRegAMD64_YMM14
- lldb_ymm15_x86_64, // CVRegAMD64_YMM15
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
- lldb_bnd0_x86_64, // CVRegBND0
- lldb_bnd1_x86_64, // CVRegBND1
- lldb_bnd2_x86_64 // CVRegBND2
+ lldb_sil_x86_64, // SIL
+ lldb_dil_x86_64, // DIL
+ lldb_bpl_x86_64, // BPL
+ lldb_spl_x86_64, // SPL
+ lldb_rax_x86_64, // RAX
+ lldb_rbx_x86_64, // RBX
+ lldb_rcx_x86_64, // RCX
+ lldb_rdx_x86_64, // RDX
+ lldb_rsi_x86_64, // RSI
+ lldb_rdi_x86_64, // RDI
+ lldb_rbp_x86_64, // RBP
+ lldb_rsp_x86_64, // RSP
+ lldb_r8_x86_64, // R8
+ lldb_r9_x86_64, // R9
+ lldb_r10_x86_64, // R10
+ lldb_r11_x86_64, // R11
+ lldb_r12_x86_64, // R12
+ lldb_r13_x86_64, // R13
+ lldb_r14_x86_64, // R14
+ lldb_r15_x86_64, // R15
+ lldb_r8l_x86_64, // R8B
+ lldb_r9l_x86_64, // R9B
+ lldb_r10l_x86_64, // R10B
+ lldb_r11l_x86_64, // R11B
+ lldb_r12l_x86_64, // R12B
+ lldb_r13l_x86_64, // R13B
+ lldb_r14l_x86_64, // R14B
+ lldb_r15l_x86_64, // R15B
+ lldb_r8w_x86_64, // R8W
+ lldb_r9w_x86_64, // R9W
+ lldb_r10w_x86_64, // R10W
+ lldb_r11w_x86_64, // R11W
+ lldb_r12w_x86_64, // R12W
+ lldb_r13w_x86_64, // R13W
+ lldb_r14w_x86_64, // R14W
+ lldb_r15w_x86_64, // R15W
+ lldb_r8d_x86_64, // R8D
+ lldb_r9d_x86_64, // R9D
+ lldb_r10d_x86_64, // R10D
+ lldb_r11d_x86_64, // R11D
+ lldb_r12d_x86_64, // R12D
+ lldb_r13d_x86_64, // R13D
+ lldb_r14d_x86_64, // R14D
+ lldb_r15d_x86_64, // R15D
+ lldb_ymm0_x86_64, // AMD64_YMM0
+ lldb_ymm1_x86_64, // AMD64_YMM1
+ lldb_ymm2_x86_64, // AMD64_YMM2
+ lldb_ymm3_x86_64, // AMD64_YMM3
+ lldb_ymm4_x86_64, // AMD64_YMM4
+ lldb_ymm5_x86_64, // AMD64_YMM5
+ lldb_ymm6_x86_64, // AMD64_YMM6
+ lldb_ymm7_x86_64, // AMD64_YMM7
+ lldb_ymm8_x86_64, // AMD64_YMM8
+ lldb_ymm9_x86_64, // AMD64_YMM9
+ lldb_ymm10_x86_64, // AMD64_YMM10
+ lldb_ymm11_x86_64, // AMD64_YMM11
+ lldb_ymm12_x86_64, // AMD64_YMM12
+ lldb_ymm13_x86_64, // AMD64_YMM13
+ lldb_ymm14_x86_64, // AMD64_YMM14
+ lldb_ymm15_x86_64, // AMD64_YMM15
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+ lldb_bnd0_x86_64, // BND0
+ lldb_bnd1_x86_64, // BND1
+ lldb_bnd2_x86_64 // BND2
};
uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
@@ -443,13 +443,13 @@ uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
register_id)];
switch (register_id) {
- case llvm::codeview::RegisterId::CVRegMXCSR:
+ case llvm::codeview::RegisterId::MXCSR:
return lldb_mxcsr_i386;
- case llvm::codeview::RegisterId::CVRegBND0:
+ case llvm::codeview::RegisterId::BND0:
return lldb_bnd0_i386;
- case llvm::codeview::RegisterId::CVRegBND1:
+ case llvm::codeview::RegisterId::BND1:
return lldb_bnd1_i386;
- case llvm::codeview::RegisterId::CVRegBND2:
+ case llvm::codeview::RegisterId::BND2:
return lldb_bnd2_i386;
default:
return LLDB_INVALID_REGNUM;
@@ -468,7 +468,7 @@ uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
}
uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
- if (register_id == llvm::codeview::RegisterId::CVRegVFRAME)
+ if (register_id == llvm::codeview::RegisterId::VFRAME)
return LLDB_REGNUM_GENERIC_FP;
return LLDB_INVALID_REGNUM;
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 05f3017819fa..ad25842f4d05 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -9,6 +9,9 @@
#include "SymbolFilePDB.h"
+#include "PDBASTParser.h"
+#include "PDBLocationToDWARFExpression.h"
+
#include "clang/Lex/Lexer.h"
#include "lldb/Core/Module.h"
@@ -46,8 +49,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/SymbolFile/PDB/PDBASTParser.h"
-#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h"
+#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
+#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"
#include <regex>
@@ -74,14 +77,32 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
}
} // namespace
+static bool ShouldUseNativeReader() {
+#if defined(_WIN32)
+ llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
+ return use_native.equals_lower("on") || use_native.equals_lower("yes") ||
+ use_native.equals_lower("1") || use_native.equals_lower("true");
+#else
+ return true;
+#endif
+}
+
void SymbolFilePDB::Initialize() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
+ if (ShouldUseNativeReader()) {
+ npdb::SymbolFileNativePDB::Initialize();
+ } else {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ DebuggerInitialize);
+ }
}
void SymbolFilePDB::Terminate() {
- PluginManager::UnregisterPlugin(CreateInstance);
+ if (ShouldUseNativeReader()) {
+ npdb::SymbolFileNativePDB::Terminate();
+ } else {
+ PluginManager::UnregisterPlugin(CreateInstance);
+ }
}
void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
@@ -246,14 +267,8 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
}
-lldb::LanguageType
-SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
- // What fields should I expect to be filled out on the SymbolContext? Is it
- // safe to assume that `sc.comp_unit` is valid?
- if (!sc.comp_unit)
- return lldb::eLanguageTypeUnknown;
-
- auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
+ auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return lldb::eLanguageTypeUnknown;
auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
@@ -262,9 +277,11 @@ SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) {
return TranslateLanguage(details->getLanguage());
}
-lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
- const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) {
- lldbassert(sc.comp_unit && sc.module_sp.get());
+lldb_private::Function *
+SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
+ CompileUnit &comp_unit) {
+ if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId()))
+ return result.get();
auto file_vm_addr = pdb_func.getVirtualAddress();
if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
@@ -272,7 +289,8 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
auto func_length = pdb_func.getLength();
AddressRange func_range =
- AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList());
+ AddressRange(file_vm_addr, func_length,
+ GetObjectFile()->GetModule()->GetSectionList());
if (!func_range.GetBaseAddress().IsValid())
return nullptr;
@@ -285,59 +303,61 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(
Mangled mangled = GetMangledForPDBFunc(pdb_func);
FunctionSP func_sp =
- std::make_shared<Function>(sc.comp_unit, pdb_func.getSymIndexId(),
+ std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(),
func_type_uid, mangled, func_type, func_range);
- sc.comp_unit->AddFunction(func_sp);
+ comp_unit.AddFunction(func_sp);
+
+ TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (!type_system)
+ return nullptr;
+ ClangASTContext *clang_type_system =
+ llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+ clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
+
return func_sp.get();
}
-size_t SymbolFilePDB::ParseCompileUnitFunctions(
- const lldb_private::SymbolContext &sc) {
- lldbassert(sc.comp_unit);
+size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
size_t func_added = 0;
- auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return 0;
auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
if (!results_up)
return 0;
while (auto pdb_func_up = results_up->getNext()) {
- auto func_sp =
- sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId());
+ auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId());
if (!func_sp) {
- if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc))
+ if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit))
++func_added;
}
}
return func_added;
}
-bool SymbolFilePDB::ParseCompileUnitLineTable(
- const lldb_private::SymbolContext &sc) {
- lldbassert(sc.comp_unit);
- if (sc.comp_unit->GetLineTable())
+bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
+ if (comp_unit.GetLineTable())
return true;
- return ParseCompileUnitLineTable(sc, 0);
+ return ParseCompileUnitLineTable(comp_unit, 0);
}
-bool SymbolFilePDB::ParseCompileUnitDebugMacros(
- const lldb_private::SymbolContext &sc) {
+bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) {
// PDB doesn't contain information about macros
return false;
}
-bool SymbolFilePDB::ParseCompileUnitSupportFiles(
- const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) {
- lldbassert(sc.comp_unit);
+bool SymbolFilePDB::ParseSupportFiles(
+ CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) {
// In theory this is unnecessary work for us, because all of this information
// is easily (and quickly) accessible from DebugInfoPDB, so caching it a
// second time seems like a waste. Unfortunately, there's no good way around
// this short of a moderate refactor since SymbolVendor depends on being able
// to cache this list.
- auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return false;
auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
@@ -345,13 +365,13 @@ bool SymbolFilePDB::ParseCompileUnitSupportFiles(
return false;
while (auto file = files->getNext()) {
- FileSpec spec(file->getFileName(), false, FileSpec::Style::windows);
+ FileSpec spec(file->getFileName(), FileSpec::Style::windows);
support_files.AppendIfUnique(spec);
}
// LLDB uses the DWARF-like file numeration (one based),
// the zeroth file is the compile unit itself
- support_files.Insert(0, *sc.comp_unit);
+ support_files.Insert(0, comp_unit);
return true;
}
@@ -364,9 +384,8 @@ bool SymbolFilePDB::ParseImportedModules(
}
static size_t ParseFunctionBlocksForPDBSymbol(
- const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr,
- const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block,
- bool is_top_parent) {
+ uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol,
+ lldb_private::Block *parent_block, bool is_top_parent) {
assert(pdb_symbol && parent_block);
size_t num_added = 0;
@@ -405,7 +424,7 @@ static size_t ParseFunctionBlocksForPDBSymbol(
break;
while (auto symbol_up = results_up->getNext()) {
num_added += ParseFunctionBlocksForPDBSymbol(
- sc, func_file_vm_addr, symbol_up.get(), block, false);
+ func_file_vm_addr, symbol_up.get(), block, false);
}
} break;
default:
@@ -414,28 +433,22 @@ static size_t ParseFunctionBlocksForPDBSymbol(
return num_added;
}
-size_t
-SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) {
- lldbassert(sc.comp_unit && sc.function);
+size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
size_t num_added = 0;
- auto uid = sc.function->GetID();
+ auto uid = func.GetID();
auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
if (!pdb_func_up)
return 0;
- Block &parent_block = sc.function->GetBlock(false);
- num_added =
- ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(),
- pdb_func_up.get(), &parent_block, true);
+ Block &parent_block = func.GetBlock(false);
+ num_added = ParseFunctionBlocksForPDBSymbol(
+ pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true);
return num_added;
}
-size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
- lldbassert(sc.module_sp.get());
- if (!sc.comp_unit)
- return 0;
+size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
size_t num_added = 0;
- auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
+ auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland)
return 0;
@@ -459,31 +472,26 @@ size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) {
// This should cause the type to get cached and stored in the `m_types`
// lookup.
- if (!ResolveTypeUID(symbol->getSymIndexId()))
- continue;
-
- ++num_added;
+ if (auto type = ResolveTypeUID(symbol->getSymIndexId())) {
+ // Resolve the type completely to avoid a completion
+ // (and so a list change, which causes an iterators invalidation)
+ // during a TypeList dumping
+ type->GetFullCompilerType();
+ ++num_added;
+ }
}
}
};
- if (sc.function) {
- auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
- sc.function->GetID());
- if (!pdb_func)
- return 0;
- ParseTypesByTagFn(*pdb_func);
- } else {
- ParseTypesByTagFn(*compiland);
-
- // Also parse global types particularly coming from this compiland.
- // Unfortunately, PDB has no compiland information for each global type. We
- // have to parse them all. But ensure we only do this once.
- static bool parse_all_global_types = false;
- if (!parse_all_global_types) {
- ParseTypesByTagFn(*m_global_scope_up);
- parse_all_global_types = true;
- }
+ ParseTypesByTagFn(*compiland);
+
+ // Also parse global types particularly coming from this compiland.
+ // Unfortunately, PDB has no compiland information for each global type. We
+ // have to parse them all. But ensure we only do this once.
+ static bool parse_all_global_types = false;
+ if (!parse_all_global_types) {
+ ParseTypesByTagFn(*m_global_scope_up);
+ parse_all_global_types = true;
}
return num_added;
}
@@ -513,7 +521,7 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (results && results->getChildCount()) {
while (auto result = results->getNext()) {
- auto cu_id = result->getCompilandId();
+ auto cu_id = GetCompilandId(*result);
// FIXME: We are not able to determine variable's compile unit.
if (cu_id == 0)
continue;
@@ -548,8 +556,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
llvm::dyn_cast_or_null<ClangASTContext>(type_system);
if (!clang_type_system)
return nullptr;
- PDBASTParser *pdb =
- llvm::dyn_cast<PDBASTParser>(clang_type_system->GetPDBParser());
+ PDBASTParser *pdb = clang_type_system->GetPDBParser();
if (!pdb)
return nullptr;
@@ -567,34 +574,109 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
return result.get();
}
+llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+ return llvm::None;
+}
+
bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
- // TODO: Implement this
- return false;
+ std::lock_guard<std::recursive_mutex> guard(
+ GetObjectFile()->GetModule()->GetMutex());
+
+ ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return false;
+
+ PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
+ if (!pdb)
+ return false;
+
+ return pdb->CompleteTypeFromPDB(compiler_type);
}
lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
- return lldb_private::CompilerDecl();
+ ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return CompilerDecl();
+
+ PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
+ if (!pdb)
+ return CompilerDecl();
+
+ auto symbol = m_session_up->getSymbolById(uid);
+ if (!symbol)
+ return CompilerDecl();
+
+ auto decl = pdb->GetDeclForSymbol(*symbol);
+ if (!decl)
+ return CompilerDecl();
+
+ return CompilerDecl(clang_ast_ctx, decl);
}
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
- // PDB always uses the translation unit decl context for everything. We can
- // improve this later but it's not easy because PDB doesn't provide a high
- // enough level of type fidelity in this area.
- return *m_tu_decl_ctx_up;
+ ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return CompilerDeclContext();
+
+ PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
+ if (!pdb)
+ return CompilerDeclContext();
+
+ auto symbol = m_session_up->getSymbolById(uid);
+ if (!symbol)
+ return CompilerDeclContext();
+
+ auto decl_context = pdb->GetDeclContextForSymbol(*symbol);
+ if (!decl_context)
+ return GetDeclContextContainingUID(uid);
+
+ return CompilerDeclContext(clang_ast_ctx, decl_context);
}
lldb_private::CompilerDeclContext
SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
- return *m_tu_decl_ctx_up;
+ ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return CompilerDeclContext();
+
+ PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
+ if (!pdb)
+ return CompilerDeclContext();
+
+ auto symbol = m_session_up->getSymbolById(uid);
+ if (!symbol)
+ return CompilerDeclContext();
+
+ auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);
+ assert(decl_context);
+
+ return CompilerDeclContext(clang_ast_ctx, decl_context);
}
void SymbolFilePDB::ParseDeclsForContext(
- lldb_private::CompilerDeclContext decl_ctx) {}
+ lldb_private::CompilerDeclContext decl_ctx) {
+ ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
+ GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus));
+ if (!clang_ast_ctx)
+ return;
+
+ PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
+ if (!pdb)
+ return;
+
+ pdb->ParseDeclsForDeclContext(
+ static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext()));
+}
uint32_t
SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
- uint32_t resolve_scope,
+ SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) {
uint32_t resolved_flags = 0;
if (resolve_scope & eSymbolContextCompUnit ||
@@ -614,7 +696,8 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
lldbassert(sc.module_sp == cu_sp->GetModule());
}
- if (resolve_scope & eSymbolContextFunction) {
+ if (resolve_scope & eSymbolContextFunction ||
+ resolve_scope & eSymbolContextBlock) {
addr_t file_vm_addr = so_addr.GetFileAddress();
auto symbol_up =
m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
@@ -624,12 +707,16 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
auto func_uid = pdb_func->getSymIndexId();
sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
if (sc.function == nullptr)
- sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
+ sc.function =
+ ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit);
if (sc.function) {
resolved_flags |= eSymbolContextFunction;
if (resolve_scope & eSymbolContextBlock) {
- Block &block = sc.function->GetBlock(true);
- sc.block = block.FindBlockByID(sc.function->GetID());
+ auto block_symbol = m_session_up->findSymbolByAddress(
+ file_vm_addr, PDB_SymType::Block);
+ auto block_id = block_symbol ? block_symbol->getSymIndexId()
+ : sc.function->GetID();
+ sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);
if (sc.block)
resolved_flags |= eSymbolContextBlock;
}
@@ -650,7 +737,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
uint32_t SymbolFilePDB::ResolveSymbolContext(
const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines,
- uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) {
+ SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
const size_t old_size = sc_list.GetSize();
if (resolve_scope & lldb::eSymbolContextCompUnit) {
// Locate all compilation units with line numbers referencing the specified
@@ -674,7 +761,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
std::string source_file = compiland->getSourceFileFullPath();
if (source_file.empty())
continue;
- FileSpec this_spec(source_file, false, FileSpec::Style::windows);
+ FileSpec this_spec(source_file, FileSpec::Style::windows);
bool need_full_match = !file_spec.GetDirectory().IsEmpty();
if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
continue;
@@ -691,7 +778,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
// table that match the requested line (or all lines if `line` == 0).
if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
eSymbolContextLineEntry)) {
- bool has_line_table = ParseCompileUnitLineTable(sc, line);
+ bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line);
if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
// The query asks for line entries, but we can't get them for the
@@ -734,7 +821,8 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
if (sc.function == nullptr) {
auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
assert(pdb_func);
- sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc);
+ sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func,
+ *sc.comp_unit);
}
if (sc.function && (resolve_scope & eSymbolContextBlock)) {
Block &block = sc.function->GetBlock(true);
@@ -759,24 +847,16 @@ uint32_t SymbolFilePDB::ResolveSymbolContext(
}
std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
- std::string decorated_name;
- auto vm_addr = pdb_data.getVirtualAddress();
- if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) {
- auto result_up =
- m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol);
- if (result_up) {
- while (auto symbol_up = result_up->getNext()) {
- if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) {
- decorated_name = symbol_up->getRawSymbol().getName();
- break;
- }
- }
- }
- }
- if (!decorated_name.empty())
- return decorated_name;
-
- return std::string();
+ // Cache public names at first
+ if (m_public_names.empty())
+ if (auto result_up =
+ m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))
+ while (auto symbol_up = result_up->getNext())
+ if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())
+ m_public_names[addr] = symbol_up->getRawSymbol().getName();
+
+ // Look up the name in the cache
+ return m_public_names.lookup(pdb_data.getVirtualAddress());
}
VariableSP SymbolFilePDB::ParseVariableForPDBData(
@@ -843,7 +923,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
uint32_t src_file_id = first_line->getSourceFileId();
auto src_file = m_session_up->getSourceFileById(src_file_id);
if (src_file) {
- FileSpec spec(src_file->getFileName(), /*resolve_path*/ false);
+ FileSpec spec(src_file->getFileName());
decl.SetFile(spec);
decl.SetColumn(first_line->getColumnNumber());
decl.SetLine(first_line->getLineNumber());
@@ -857,7 +937,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData(
if (scope == eValueTypeVariableLocal) {
if (sc.function) {
context_scope = sc.function->GetBlock(true).FindBlockByID(
- pdb_data.getClassParentId());
+ pdb_data.getLexicalParentId());
if (context_scope == nullptr)
context_scope = sc.function;
}
@@ -937,6 +1017,9 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
if (variable_list)
variable_list->AddVariableIfUnique(var_sp);
++num_added;
+ PDBASTParser *ast = GetPDBAstParser();
+ if (ast)
+ ast->GetDeclForSymbol(*pdb_data);
}
}
}
@@ -959,9 +1042,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
if (name.IsEmpty())
return 0;
- auto results =
- m_global_scope_up->findChildren(PDB_SymType::Data, name.GetStringRef(),
- PDB_NameSearchFlags::NS_CaseSensitive);
+ auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
if (!results)
return 0;
@@ -976,11 +1057,19 @@ uint32_t SymbolFilePDB::FindGlobalVariables(
sc.module_sp = m_obj_file->GetModule();
lldbassert(sc.module_sp.get());
- sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
+ if (!name.GetStringRef().equals(
+ MSVCUndecoratedNameParser::DropScope(pdb_data->getName())))
+ continue;
+
+ sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
// FIXME: We are not able to determine the compile unit.
if (sc.comp_unit == nullptr)
continue;
+ if (parent_decl_ctx && GetDeclContextContainingUID(
+ result->getSymIndexId()) != *parent_decl_ctx)
+ continue;
+
ParseVariables(sc, *pdb_data, &variables);
matches = variables.GetSize() - old_size;
}
@@ -1013,7 +1102,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression &regex,
sc.module_sp = m_obj_file->GetModule();
lldbassert(sc.module_sp.get());
- sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get();
+ sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
// FIXME: We are not able to determine the compile unit.
if (sc.comp_unit == nullptr)
continue;
@@ -1033,7 +1122,7 @@ bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
if (!sc.comp_unit)
return false;
sc.module_sp = sc.comp_unit->GetModule();
- sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc);
+ sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit);
if (!sc.function)
return false;
@@ -1075,22 +1164,11 @@ void SymbolFilePDB::CacheFunctionNames() {
// Class. We won't bother to check if the parent is UDT or Enum here.
m_func_method_names.Append(ConstString(name), uid);
- ConstString cstr_name(name);
-
// To search a method name, like NS::Class:MemberFunc, LLDB searches
// its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
// not have inforamtion of this, we extract base names and cache them
// by our own effort.
- llvm::StringRef basename;
- CPlusPlusLanguage::MethodName cpp_method(cstr_name);
- if (cpp_method.IsValid()) {
- llvm::StringRef context;
- basename = cpp_method.GetBasename();
- if (basename.empty())
- CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(),
- context, basename);
- }
-
+ llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
if (!basename.empty())
m_func_base_names.Append(ConstString(basename), uid);
else {
@@ -1103,11 +1181,12 @@ void SymbolFilePDB::CacheFunctionNames() {
} else {
// Handle not-method symbols.
- // The function name might contain namespace, or its lexical scope. It
- // is not safe to get its base name by applying same scheme as we deal
- // with the method names.
- // FIXME: Remove namespace if function is static in a scope.
- m_func_base_names.Append(ConstString(name), uid);
+ // The function name might contain namespace, or its lexical scope.
+ llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
+ if (!basename.empty())
+ m_func_base_names.Append(ConstString(basename), uid);
+ else
+ m_func_base_names.Append(ConstString(name), uid);
if (name == "main") {
m_func_full_names.Append(ConstString(name), uid);
@@ -1157,7 +1236,7 @@ void SymbolFilePDB::CacheFunctionNames() {
uint32_t SymbolFilePDB::FindFunctions(
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
+ FunctionNameType name_type_mask, bool include_inlines, bool append,
lldb_private::SymbolContextList &sc_list) {
if (!append)
sc_list.Clear();
@@ -1177,20 +1256,28 @@ uint32_t SymbolFilePDB::FindFunctions(
CacheFunctionNames();
std::set<uint32_t> resolved_ids;
- auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids,
- this](UniqueCStringMap<uint32_t> &Names) {
+ auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list,
+ &resolved_ids](UniqueCStringMap<uint32_t> &Names) {
std::vector<uint32_t> ids;
- if (Names.GetValues(name, ids)) {
- for (auto id : ids) {
- if (resolved_ids.find(id) == resolved_ids.end()) {
- if (ResolveFunction(id, include_inlines, sc_list))
- resolved_ids.insert(id);
- }
- }
+ if (!Names.GetValues(name, ids))
+ return;
+
+ for (uint32_t id : ids) {
+ if (resolved_ids.find(id) != resolved_ids.end())
+ continue;
+
+ if (parent_decl_ctx &&
+ GetDeclContextContainingUID(id) != *parent_decl_ctx)
+ continue;
+
+ if (ResolveFunction(id, include_inlines, sc_list))
+ resolved_ids.insert(id);
}
};
if (name_type_mask & eFunctionNameTypeFull) {
ResolveFn(m_func_full_names);
+ ResolveFn(m_func_base_names);
+ ResolveFn(m_func_method_names);
}
if (name_type_mask & eFunctionNameTypeBase) {
ResolveFn(m_func_base_names);
@@ -1236,8 +1323,59 @@ void SymbolFilePDB::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) {}
+void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
+ std::set<lldb::addr_t> sym_addresses;
+ for (size_t i = 0; i < symtab.GetNumSymbols(); i++)
+ sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
+
+ auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();
+ if (!results)
+ return;
+
+ auto section_list = m_obj_file->GetSectionList();
+ if (!section_list)
+ return;
+
+ while (auto pub_symbol = results->getNext()) {
+ auto section_idx = pub_symbol->getAddressSection() - 1;
+ if (section_idx >= section_list->GetSize())
+ continue;
+
+ auto section = section_list->GetSectionAtIndex(section_idx);
+ if (!section)
+ continue;
+
+ auto offset = pub_symbol->getAddressOffset();
+
+ auto file_addr = section->GetFileAddress() + offset;
+ if (sym_addresses.find(file_addr) != sym_addresses.end())
+ continue;
+ sym_addresses.insert(file_addr);
+
+ auto size = pub_symbol->getLength();
+ symtab.AddSymbol(
+ Symbol(pub_symbol->getSymIndexId(), // symID
+ pub_symbol->getName().c_str(), // name
+ true, // name_is_mangled
+ pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
+ true, // external
+ false, // is_debug
+ false, // is_trampoline
+ false, // is_artificial
+ section, // section_sp
+ offset, // value
+ size, // size
+ size != 0, // size_is_valid
+ false, // contains_linker_annotations
+ 0 // flags
+ ));
+ }
+
+ symtab.CalculateSymbolSizes();
+ symtab.Finalize();
+}
+
uint32_t SymbolFilePDB::FindTypes(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append,
uint32_t max_matches,
@@ -1253,14 +1391,20 @@ uint32_t SymbolFilePDB::FindTypes(
searched_symbol_files.clear();
searched_symbol_files.insert(this);
- std::string name_str = name.AsCString();
-
// There is an assumption 'name' is not a regex
- FindTypesByName(name_str, max_matches, types);
+ FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
return types.GetSize();
}
+void SymbolFilePDB::DumpClangAST(Stream &s) {
+ auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ auto clang = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang)
+ return;
+ clang->Dump(s);
+}
+
void SymbolFilePDB::FindTypesByRegex(
const lldb_private::RegularExpression &regex, uint32_t max_matches,
lldb_private::TypeMap &types) {
@@ -1316,14 +1460,14 @@ void SymbolFilePDB::FindTypesByRegex(
}
}
-void SymbolFilePDB::FindTypesByName(const std::string &name,
- uint32_t max_matches,
- lldb_private::TypeMap &types) {
+void SymbolFilePDB::FindTypesByName(
+ llvm::StringRef name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches, lldb_private::TypeMap &types) {
std::unique_ptr<IPDBEnumSymbols> results;
if (name.empty())
return;
- results = m_global_scope_up->findChildren(PDB_SymType::None, name,
- PDB_NameSearchFlags::NS_Default);
+ results = m_global_scope_up->findAllChildren(PDB_SymType::None);
if (!results)
return;
@@ -1332,6 +1476,11 @@ void SymbolFilePDB::FindTypesByName(const std::string &name,
while (auto result = results->getNext()) {
if (max_matches > 0 && matches >= max_matches)
break;
+
+ if (MSVCUndecoratedNameParser::DropScope(
+ result->getRawSymbol().getName()) != name)
+ continue;
+
switch (result->getSymTag()) {
case PDB_SymType::Enum:
case PDB_SymType::UDT:
@@ -1348,6 +1497,10 @@ void SymbolFilePDB::FindTypesByName(const std::string &name,
if (!ResolveTypeUID(result->getSymIndexId()))
continue;
+ if (parent_decl_ctx && GetDeclContextContainingUID(
+ result->getSymIndexId()) != *parent_decl_ctx)
+ continue;
+
auto iter = m_types.find(result->getSymIndexId());
if (iter == m_types.end())
continue;
@@ -1417,7 +1570,7 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
}
size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ TypeClass type_mask,
lldb_private::TypeList &type_list) {
TypeCollection type_collection;
uint32_t old_size = type_list.GetSize();
@@ -1454,11 +1607,40 @@ SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
return type_system;
}
+PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
+ auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return nullptr;
+
+ return clang_type_system->GetPDBParser();
+}
+
+
lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) {
- return lldb_private::CompilerDeclContext();
+ auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ auto clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(type_system);
+ if (!clang_type_system)
+ return CompilerDeclContext();
+
+ PDBASTParser *pdb = clang_type_system->GetPDBParser();
+ if (!pdb)
+ return CompilerDeclContext();
+
+ clang::DeclContext *decl_context = nullptr;
+ if (parent_decl_ctx)
+ decl_context = static_cast<clang::DeclContext *>(
+ parent_decl_ctx->GetOpaqueDeclContext());
+
+ auto namespace_decl =
+ pdb->FindNamespaceDecl(decl_context, name.GetStringRef());
+ if (!namespace_decl)
+ return CompilerDeclContext();
+
+ return CompilerDeclContext(type_system,
+ static_cast<clang::DeclContext *>(namespace_decl));
}
lldb_private::ConstString SymbolFilePDB::GetPluginName() {
@@ -1516,11 +1698,9 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
return cu_sp;
}
-bool SymbolFilePDB::ParseCompileUnitLineTable(
- const lldb_private::SymbolContext &sc, uint32_t match_line) {
- lldbassert(sc.comp_unit);
-
- auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID());
+bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
+ uint32_t match_line) {
+ auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
if (!compiland_up)
return false;
@@ -1530,10 +1710,10 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
// to do a mapping so that we can hand out indices.
llvm::DenseMap<uint32_t, uint32_t> index_map;
BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
- auto line_table = llvm::make_unique<LineTable>(sc.comp_unit);
+ auto line_table = llvm::make_unique<LineTable>(&comp_unit);
// Find contributions to `compiland` from all source and header files.
- std::string path = sc.comp_unit->GetPath();
+ std::string path = comp_unit.GetPath();
auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
if (!files)
return false;
@@ -1617,7 +1797,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable(
}
if (line_table->GetSize()) {
- sc.comp_unit->SetLineTable(line_table.release());
+ comp_unit.SetLineTable(line_table.release());
return true;
}
return false;
@@ -1747,3 +1927,68 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
return false;
}
+
+uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {
+ static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {
+ return lhs < rhs.Offset;
+ };
+
+ // Cache section contributions
+ if (m_sec_contribs.empty()) {
+ if (auto SecContribs = m_session_up->getSectionContribs()) {
+ while (auto SectionContrib = SecContribs->getNext()) {
+ auto comp_id = SectionContrib->getCompilandId();
+ if (!comp_id)
+ continue;
+
+ auto sec = SectionContrib->getAddressSection();
+ auto &sec_cs = m_sec_contribs[sec];
+
+ auto offset = SectionContrib->getAddressOffset();
+ auto it =
+ std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper);
+
+ auto size = SectionContrib->getLength();
+ sec_cs.insert(it, {offset, size, comp_id});
+ }
+ }
+ }
+
+ // Check by line number
+ if (auto Lines = data.getLineNumbers()) {
+ if (auto FirstLine = Lines->getNext())
+ return FirstLine->getCompilandId();
+ }
+
+ // Retrieve section + offset
+ uint32_t DataSection = data.getAddressSection();
+ uint32_t DataOffset = data.getAddressOffset();
+ if (DataSection == 0) {
+ if (auto RVA = data.getRelativeVirtualAddress())
+ m_session_up->addressForRVA(RVA, DataSection, DataOffset);
+ }
+
+ if (DataSection) {
+ // Search by section contributions
+ auto &sec_cs = m_sec_contribs[DataSection];
+ auto it =
+ std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper);
+ if (it != sec_cs.begin()) {
+ --it;
+ if (DataOffset < it->Offset + it->Size)
+ return it->CompilandId;
+ }
+ } else {
+ // Search in lexical tree
+ auto LexParentId = data.getLexicalParentId();
+ while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {
+ if (LexParent->getSymTag() == PDB_SymType::Exe)
+ break;
+ if (LexParent->getSymTag() == PDB_SymType::Compiland)
+ return LexParentId;
+ LexParentId = LexParent->getRawSymbol().getLexicalParentId();
+ }
+ }
+
+ return 0;
+}
diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 96b62d68a6c2..81288093b7d8 100644
--- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -20,6 +20,8 @@
#include "llvm/DebugInfo/PDB/PDB.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+class PDBASTParser;
+
class SymbolFilePDB : public lldb_private::SymbolFile {
public:
//------------------------------------------------------------------
@@ -58,33 +60,32 @@ public:
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+ bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
- bool ParseCompileUnitSupportFiles(
- const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) override;
+ bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+ lldb_private::FileSpecList &support_files) override;
+
+ size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
-
- size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseBlocksRecursive(lldb_private::Function &func) override;
size_t
ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override;
bool CompleteType(lldb_private::CompilerType &compiler_type) override;
@@ -100,12 +101,13 @@ public:
ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
- uint32_t resolve_scope,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
uint32_t
ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line,
- bool check_inlines, uint32_t resolve_scope,
+ bool check_inlines,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContextList &sc_list) override;
uint32_t
@@ -121,8 +123,8 @@ public:
uint32_t
FindFunctions(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask, bool include_inlines, bool append,
- lldb_private::SymbolContextList &sc_list) override;
+ lldb::FunctionNameType name_type_mask, bool include_inlines,
+ bool append, lldb_private::SymbolContextList &sc_list) override;
uint32_t FindFunctions(const lldb_private::RegularExpression &regex,
bool include_inlines, bool append,
@@ -132,9 +134,10 @@ public:
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) override;
+ void AddSymbols(lldb_private::Symtab &symtab) override;
+
uint32_t
- FindTypes(const lldb_private::SymbolContext &sc,
- const lldb_private::ConstString &name,
+ FindTypes(const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx,
bool append, uint32_t max_matches,
llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
@@ -149,14 +152,13 @@ public:
lldb_private::TypeList *GetTypeList() override;
size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language) override;
lldb_private::CompilerDeclContext FindNamespace(
- const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
@@ -168,19 +170,29 @@ public:
const llvm::pdb::IPDBSession &GetPDBSession() const;
+ void DumpClangAST(lldb_private::Stream &s) override;
+
private:
+ struct SecContribInfo {
+ uint32_t Offset;
+ uint32_t Size;
+ uint32_t CompilandId;
+ };
+ using SecContribsMap = std::map<uint32_t, std::vector<SecContribInfo>>;
+
lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id,
uint32_t index = UINT32_MAX);
- bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc,
+ bool ParseCompileUnitLineTable(lldb_private::CompileUnit &comp_unit,
uint32_t match_line);
void BuildSupportFileIdToSupportFileIndexMap(
const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
- void FindTypesByName(const std::string &name, uint32_t max_matches,
- lldb_private::TypeMap &types);
+ void FindTypesByName(llvm::StringRef name,
+ const lldb_private::CompilerDeclContext *parent_decl_ctx,
+ uint32_t max_matches, lldb_private::TypeMap &types);
std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data);
@@ -203,11 +215,13 @@ private:
lldb_private::Function *
ParseCompileUnitFunctionForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func,
- const lldb_private::SymbolContext &sc);
+ lldb_private::CompileUnit &comp_unit);
void GetCompileUnitIndex(const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
uint32_t &index);
+ PDBASTParser *GetPDBAstParser();
+
std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
GetPDBCompilandByUID(uint32_t uid);
@@ -226,9 +240,14 @@ private:
bool DeclContextMatchesThisSymbolFile(
const lldb_private::CompilerDeclContext *decl_ctx);
+ uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data);
+
llvm::DenseMap<uint32_t, lldb::CompUnitSP> m_comp_units;
llvm::DenseMap<uint32_t, lldb::TypeSP> m_types;
llvm::DenseMap<uint32_t, lldb::VariableSP> m_variables;
+ llvm::DenseMap<uint64_t, std::string> m_public_names;
+
+ SecContribsMap m_sec_contribs;
std::vector<lldb::TypeSP> m_builtin_types;
std::unique_ptr<llvm::pdb::IPDBSession> m_session_up;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 64e2daf60ee5..08778bd1ba70 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -46,7 +46,7 @@ SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) {
}
size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ TypeClass type_mask,
lldb_private::TypeList &type_list) {
return 0;
}
@@ -131,15 +131,13 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) {
return cu_sp;
}
-lldb::LanguageType
-SymbolFileSymtab::ParseCompileUnitLanguage(const SymbolContext &sc) {
+lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) {
return eLanguageTypeUnknown;
}
-size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
+size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
size_t num_added = 0;
// We must at least have a valid compile unit
- assert(sc.comp_unit != NULL);
const Symtab *symtab = m_obj_file->GetSymtab();
const Symbol *curr_symbol = NULL;
const Symbol *next_symbol = NULL;
@@ -185,7 +183,7 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
}
FunctionSP func_sp(
- new Function(sc.comp_unit,
+ new Function(&comp_unit,
symbol_idx, // UserID is the DIE offset
LLDB_INVALID_UID, // We don't have any type info
// for this function
@@ -194,7 +192,7 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
func_range)); // first address range
if (func_sp.get() != NULL) {
- sc.comp_unit->AddFunction(func_sp);
+ comp_unit.AddFunction(func_sp);
++num_added;
}
}
@@ -207,16 +205,16 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) {
return num_added;
}
-bool SymbolFileSymtab::ParseCompileUnitLineTable(const SymbolContext &sc) {
- return false;
-}
+size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; }
-bool SymbolFileSymtab::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
+bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; }
+
+bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) {
return false;
}
-bool SymbolFileSymtab::ParseCompileUnitSupportFiles(
- const SymbolContext &sc, FileSpecList &support_files) {
+bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit,
+ FileSpecList &support_files) {
return false;
}
@@ -225,11 +223,7 @@ bool SymbolFileSymtab::ParseImportedModules(
return false;
}
-size_t SymbolFileSymtab::ParseFunctionBlocks(const SymbolContext &sc) {
- return 0;
-}
-
-size_t SymbolFileSymtab::ParseTypes(const SymbolContext &sc) { return 0; }
+size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; }
size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) {
return 0;
@@ -239,12 +233,18 @@ Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
return NULL;
}
+llvm::Optional<SymbolFile::ArrayInfo>
+SymbolFileSymtab::GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
+ return llvm::None;
+}
+
bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) {
return false;
}
uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr,
- uint32_t resolve_scope,
+ SymbolContextItem resolve_scope,
SymbolContext &sc) {
if (m_obj_file->GetSymtab() == NULL)
return 0;
diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
index d1887a707ea6..e4ec7a181333 100644
--- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -10,13 +10,9 @@
#ifndef liblldb_SymbolFileSymtab_h_
#define liblldb_SymbolFileSymtab_h_
-// C Includes
-// C++ Includes
#include <map>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Symtab.h"
@@ -53,42 +49,41 @@ public:
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override;
lldb::LanguageType
- ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override;
+ ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
- size_t
- ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override;
+ size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override;
+ bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
- bool
- ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override;
+ bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
- bool ParseCompileUnitSupportFiles(
- const lldb_private::SymbolContext &sc,
- lldb_private::FileSpecList &support_files) override;
+ bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
+ lldb_private::FileSpecList &support_files) override;
+
+ size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
bool ParseImportedModules(
const lldb_private::SymbolContext &sc,
std::vector<lldb_private::ConstString> &imported_modules) override;
- size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override;
-
- size_t ParseTypes(const lldb_private::SymbolContext &sc) override;
+ size_t ParseBlocksRecursive(lldb_private::Function &func) override;
size_t
ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+ llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
+ lldb::user_id_t type_uid,
+ const lldb_private::ExecutionContext *exe_ctx) override;
bool CompleteType(lldb_private::CompilerType &compiler_type) override;
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
- uint32_t resolve_scope,
+ lldb::SymbolContextItem resolve_scope,
lldb_private::SymbolContext &sc) override;
size_t GetTypes(lldb_private::SymbolContextScope *sc_scope,
- uint32_t type_mask,
+ lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override;
//------------------------------------------------------------------
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
index d24510966878..425b612d786f 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -101,16 +101,17 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
module_spec.GetFileSpec() = obj_file->GetFileSpec();
- module_spec.GetFileSpec().ResolvePath();
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
module_spec.GetSymbolFileSpec() = fspec;
module_spec.GetUUID() = uuid;
FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec);
if (dsym_fspec) {
DataBufferSP dsym_file_data_sp;
lldb::offset_t dsym_file_data_offset = 0;
- ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
- module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
- dsym_file_data_sp, dsym_file_data_offset);
+ ObjectFileSP dsym_objfile_sp =
+ ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
+ FileSystem::Instance().GetByteSize(dsym_fspec),
+ dsym_file_data_sp, dsym_file_data_offset);
if (dsym_objfile_sp) {
// This objfile is for debugging purposes. Sadly, ObjectFileELF won't
// be able to figure this out consistently as the symbol file may not
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
index e7aeebc96b94..b0d956e31dc9 100644
--- a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
+++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h
@@ -10,10 +10,6 @@
#ifndef liblldb_SymbolVendorELF_h_
#define liblldb_SymbolVendorELF_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index c69eb7fd51c7..169eed817566 100644
--- a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -153,9 +153,10 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
if (dsym_fspec) {
DataBufferSP dsym_file_data_sp;
lldb::offset_t dsym_file_data_offset = 0;
- dsym_objfile_sp = ObjectFile::FindPlugin(
- module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(),
- dsym_file_data_sp, dsym_file_data_offset);
+ dsym_objfile_sp =
+ ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
+ FileSystem::Instance().GetByteSize(dsym_fspec),
+ dsym_file_data_sp, dsym_file_data_offset);
if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) {
// We need a XML parser if we hope to parse a plist...
if (XMLDocument::XMLEnabled()) {
@@ -172,8 +173,8 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
resources[strlen("/Contents/Resources/")] = '\0';
snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
"%s%s.plist", dsym_path, uuid_str.c_str());
- FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
- if (dsym_uuid_plist_spec.Exists()) {
+ FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path);
+ if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) {
ApplePropertyList plist(dsym_uuid_plist_path);
if (plist) {
std::string DBGBuildSourcePath;
@@ -236,14 +237,15 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
// object is DBGSourcePath
std::string DBGSourcePath =
object->GetStringValue();
- if (new_style_source_remapping_dictionary ==
- false &&
+ if (!new_style_source_remapping_dictionary &&
!original_DBGSourcePath_value.empty()) {
DBGSourcePath = original_DBGSourcePath_value;
}
if (DBGSourcePath[0] == '~') {
FileSpec resolved_source_path(
- DBGSourcePath.c_str(), true);
+ DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(
+ resolved_source_path);
DBGSourcePath =
resolved_source_path.GetPath();
}
@@ -256,8 +258,8 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
// 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);
+ FileSpec build_path(key.AsCString());
+ FileSpec source_path(DBGSourcePath.c_str());
build_path.RemoveLastPathComponent();
build_path.RemoveLastPathComponent();
source_path.RemoveLastPathComponent();
@@ -280,8 +282,8 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
if (!DBGBuildSourcePath.empty() &&
!DBGSourcePath.empty()) {
if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(),
- true);
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
DBGSourcePath = resolved_source_path.GetPath();
}
module_sp->GetSourceMappingList().Append(
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index 007a59378fc5..43e401330c5c 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -10,10 +10,6 @@
#include "AppleGetItemInfoHandler.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
@@ -242,7 +238,7 @@ AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
error.Clear();
- if (thread.SafeToCallFunctions() == false) {
+ if (!thread.SafeToCallFunctions()) {
if (log)
log->Printf("Not safe to call functions on thread 0x%" PRIx64,
thread.GetID());
@@ -340,6 +336,7 @@ AppleGetItemInfoHandler::GetItemInfo(Thread &thread, uint64_t item,
options.SetStopOthers(true);
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTryAllThreads(false);
+ options.SetIsForUtilityExpr(true);
thread.CalculateExecutionContext(exe_ctx);
if (!m_get_item_info_impl_code) {
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
index 373808e0f7e8..ac3711ead878 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.h
@@ -10,14 +10,10 @@
#ifndef lldb_AppleGetItemInfoHandler_h_
#define lldb_AppleGetItemInfoHandler_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
index 0de32bf11416..78e50e673af0 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -10,10 +10,6 @@
#include "AppleGetPendingItemsHandler.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
@@ -245,7 +241,7 @@ AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
error.Clear();
- if (thread.SafeToCallFunctions() == false) {
+ if (!thread.SafeToCallFunctions()) {
if (log)
log->Printf("Not safe to call functions on thread 0x%" PRIx64,
thread.GetID());
@@ -349,6 +345,7 @@ AppleGetPendingItemsHandler::GetPendingItems(Thread &thread, addr_t queue,
options.SetStopOthers(true);
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTryAllThreads(false);
+ options.SetIsForUtilityExpr(true);
thread.CalculateExecutionContext(exe_ctx);
if (get_pending_items_caller == NULL) {
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
index 139e05b1b6c9..d35a72c2ff43 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.h
@@ -11,14 +11,10 @@
#ifndef lldb_AppleGetPendingItemsHandler_h_
#define lldb_AppleGetPendingItemsHandler_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-public.h"
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
index 7855b3603a3a..245ff6742b43 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -9,10 +9,6 @@
#include "AppleGetQueuesHandler.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DiagnosticManager.h"
@@ -247,7 +243,7 @@ AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
error.Clear();
- if (thread.SafeToCallFunctions() == false) {
+ if (!thread.SafeToCallFunctions()) {
if (log)
log->Printf("Not safe to call functions on thread 0x%" PRIx64,
thread.GetID());
@@ -354,6 +350,7 @@ AppleGetQueuesHandler::GetCurrentQueues(Thread &thread, addr_t page_to_free,
options.SetStopOthers(true);
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTryAllThreads(false);
+ options.SetIsForUtilityExpr(true);
thread.CalculateExecutionContext(exe_ctx);
ExpressionResults func_call_ret;
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
index f1c79044496f..0d8e4dc64a68 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.h
@@ -10,14 +10,10 @@
#ifndef lldb_AppleGetQueuesHandler_h_
#define lldb_AppleGetQueuesHandler_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-public.h"
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
index 09ab6600a9f0..ede81333a3e6 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -10,10 +10,6 @@
#include "AppleGetThreadItemInfoHandler.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
@@ -252,7 +248,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
error.Clear();
- if (thread.SafeToCallFunctions() == false) {
+ if (!thread.SafeToCallFunctions()) {
if (log)
log->Printf("Not safe to call functions on thread 0x%" PRIx64,
thread.GetID());
@@ -351,6 +347,7 @@ AppleGetThreadItemInfoHandler::GetThreadItemInfo(Thread &thread,
options.SetStopOthers(true);
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTryAllThreads(false);
+ options.SetIsForUtilityExpr(true);
thread.CalculateExecutionContext(exe_ctx);
if (!m_get_thread_item_info_impl_code) {
diff --git a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
index 62730809e0d1..47e196102362 100644
--- a/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
+++ b/source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.h
@@ -11,14 +11,10 @@
#ifndef lldb_AppleGetThreadItemInfoHandler_h_
#define lldb_AppleGetThreadItemInfoHandler_h_
-// C Includes
-// C++ Includes
#include <map>
#include <mutex>
#include <vector>
-// Other libraries and framework includes
-// Project includes
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-public.h"
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 4748d5e8622e..e61f04e489e8 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -59,6 +59,7 @@ SystemRuntime *SystemRuntimeMacOSX::CreateInstance(Process *process) {
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
+ // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS:
create = triple_ref.getVendor() == llvm::Triple::Apple;
break;
default:
@@ -276,7 +277,7 @@ void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
// libdispatch symbols were in libSystem.B.dylib up through Mac OS X 10.6
// ("Snow Leopard")
- ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib", false));
+ ModuleSpec libSystem_module_spec(FileSpec("libSystem.B.dylib"));
ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
libSystem_module_spec));
if (module_sp)
@@ -286,7 +287,7 @@ void SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress() {
// libdispatch symbols are in their own dylib as of Mac OS X 10.7 ("Lion")
// and later
if (dispatch_queue_offsets_symbol == NULL) {
- ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib", false));
+ ModuleSpec libdispatch_module_spec(FileSpec("libdispatch.dylib"));
module_sp = m_process->GetTarget().GetImages().FindFirstModule(
libdispatch_module_spec);
if (module_sp)
@@ -330,7 +331,7 @@ void SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress() {
"pthread_layout_offsets");
const Symbol *libpthread_layout_offsets_symbol = NULL;
- ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib", false));
+ ModuleSpec libpthread_module_spec(FileSpec("libsystem_pthread.dylib"));
ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
libpthread_module_spec));
if (module_sp) {
@@ -378,7 +379,7 @@ void SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress() {
"dispatch_tsd_indexes");
const Symbol *libdispatch_tsd_indexes_symbol = NULL;
- ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib", false));
+ ModuleSpec libpthread_module_spec(FileSpec("libdispatch.dylib"));
ModuleSP module_sp(m_process->GetTarget().GetImages().FindFirstModule(
libpthread_module_spec));
if (module_sp) {
diff --git a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
index 2dc5740da9b6..5fa78cee4640 100644
--- a/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
+++ b/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h
@@ -10,14 +10,11 @@
#ifndef liblldb_SystemRuntimeMacOSX_h_
#define liblldb_SystemRuntimeMacOSX_h_
-// C Includes
-// C++ Includes
#include <mutex>
#include <string>
#include <vector>
// Other libraries and framework include
-// Project includes
#include "lldb/Core/ModuleList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/QueueItem.h"
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
index 54e182b30b6f..b70c2c44d3e6 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -606,7 +606,7 @@ bool UnwindAssemblyInstEmulation::WriteRegister(
assert(
(generic_regnum == LLDB_REGNUM_GENERIC_PC ||
generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) &&
- "eInfoTypeISA used for poping a register other the the PC/FLAGS");
+ "eInfoTypeISA used for popping a register other the PC/FLAGS");
if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS) {
m_curr_row->SetRegisterLocationToSame(reg_num,
false /*must_replace*/);
diff --git a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
index e587c93b427c..5539b5217e9e 100644
--- a/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
+++ b/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h
@@ -10,14 +10,10 @@
#ifndef liblldb_UnwindAssemblyInstEmulation_h_
#define liblldb_UnwindAssemblyInstEmulation_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/UnwindAssembly.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/lldb-private.h"
class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly {
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
index 327d0b0e4f71..04f9cbbf03ae 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
@@ -92,7 +92,7 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
// assembly parsing instead.
if (first_row->GetCFAValue().GetValueType() !=
- UnwindPlan::Row::CFAValue::isRegisterPlusOffset ||
+ UnwindPlan::Row::FAValue::isRegisterPlusOffset ||
RegisterNumber(thread, unwind_plan.GetRegisterKind(),
first_row->GetCFAValue().GetRegisterNumber()) !=
sp_regnum ||
@@ -100,10 +100,10 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite(
return false;
}
UnwindPlan::Row::RegisterLocation first_row_pc_loc;
- if (first_row->GetRegisterInfo(
+ if (!first_row->GetRegisterInfo(
pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()),
- first_row_pc_loc) == false ||
- first_row_pc_loc.IsAtCFAPlusOffset() == false ||
+ first_row_pc_loc) ||
+ !first_row_pc_loc.IsAtCFAPlusOffset() ||
first_row_pc_loc.GetOffset() != -wordsize) {
return false;
}
diff --git a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
index 2beaa4a6510a..c4052a8489da 100644
--- a/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
+++ b/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h
@@ -10,12 +10,8 @@
#ifndef liblldb_UnwindAssembly_x86_h_
#define liblldb_UnwindAssembly_x86_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
#include "x86AssemblyInspectionEngine.h"
-// Project includes
#include "lldb/Target/UnwindAssembly.h"
#include "lldb/lldb-private.h"
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 10a56980594f..f8e70204e509 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -59,6 +59,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {
m_machine_ip_regnum = k_machine_eip;
m_machine_sp_regnum = k_machine_esp;
m_machine_fp_regnum = k_machine_ebp;
+ m_machine_alt_fp_regnum = k_machine_ebx;
m_wordsize = 4;
struct lldb_reg_info reginfo;
@@ -84,6 +85,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {
m_machine_ip_regnum = k_machine_rip;
m_machine_sp_regnum = k_machine_rsp;
m_machine_fp_regnum = k_machine_rbp;
+ m_machine_alt_fp_regnum = k_machine_rbx;
m_wordsize = 8;
struct lldb_reg_info reginfo;
@@ -135,6 +137,8 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP &reg_ctx) {
m_lldb_sp_regnum = lldb_regno;
if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
m_lldb_fp_regnum = lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno))
+ m_lldb_alt_fp_regnum = lldb_regno;
if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
m_lldb_ip_regnum = lldb_regno;
@@ -160,6 +164,7 @@ void x86AssemblyInspectionEngine::Initialize(
m_machine_ip_regnum = k_machine_eip;
m_machine_sp_regnum = k_machine_esp;
m_machine_fp_regnum = k_machine_ebp;
+ m_machine_alt_fp_regnum = k_machine_ebx;
m_wordsize = 4;
struct lldb_reg_info reginfo;
@@ -185,6 +190,7 @@ void x86AssemblyInspectionEngine::Initialize(
m_machine_ip_regnum = k_machine_rip;
m_machine_sp_regnum = k_machine_rsp;
m_machine_fp_regnum = k_machine_rbp;
+ m_machine_alt_fp_regnum = k_machine_rbx;
m_wordsize = 8;
struct lldb_reg_info reginfo;
@@ -239,6 +245,8 @@ void x86AssemblyInspectionEngine::Initialize(
m_lldb_sp_regnum = lldb_regno;
if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno))
m_lldb_fp_regnum = lldb_regno;
+ if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno))
+ m_lldb_alt_fp_regnum = lldb_regno;
if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno))
m_lldb_ip_regnum = lldb_regno;
@@ -296,26 +304,20 @@ bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) {
// pushq %rbp [0x55]
bool x86AssemblyInspectionEngine::push_rbp_pattern_p() {
uint8_t *p = m_cur_insn;
- if (*p == 0x55)
- return true;
- return false;
+ return *p == 0x55;
}
// pushq $0 ; the first instruction in start() [0x6a 0x00]
bool x86AssemblyInspectionEngine::push_0_pattern_p() {
uint8_t *p = m_cur_insn;
- if (*p == 0x6a && *(p + 1) == 0x0)
- return true;
- return false;
+ return *p == 0x6a && *(p + 1) == 0x0;
}
// pushq $0
// pushl $0
bool x86AssemblyInspectionEngine::push_imm_pattern_p() {
uint8_t *p = m_cur_insn;
- if (*p == 0x68 || *p == 0x6a)
- return true;
- return false;
+ return *p == 0x68 || *p == 0x6a;
}
// pushl imm8(%esp)
@@ -387,6 +389,45 @@ bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() {
return false;
}
+// movq %rsp, %rbx [0x48 0x8b 0xdc] or [0x48 0x89 0xe3]
+// movl %esp, %ebx [0x8b 0xdc] or [0x89 0xe3]
+bool x86AssemblyInspectionEngine::mov_rsp_rbx_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ if (*(p) == 0x8b && *(p + 1) == 0xdc)
+ return true;
+ if (*(p) == 0x89 && *(p + 1) == 0xe3)
+ return true;
+ return false;
+}
+
+// movq %rbp, %rsp [0x48 0x8b 0xe5] or [0x48 0x89 0xec]
+// movl %ebp, %esp [0x8b 0xe5] or [0x89 0xec]
+bool x86AssemblyInspectionEngine::mov_rbp_rsp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ if (*(p) == 0x8b && *(p + 1) == 0xe5)
+ return true;
+ if (*(p) == 0x89 && *(p + 1) == 0xec)
+ return true;
+ return false;
+}
+
+// movq %rbx, %rsp [0x48 0x8b 0xe3] or [0x48 0x89 0xdc]
+// movl %ebx, %esp [0x8b 0xe3] or [0x89 0xdc]
+bool x86AssemblyInspectionEngine::mov_rbx_rsp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+ if (*(p) == 0x8b && *(p + 1) == 0xe3)
+ return true;
+ if (*(p) == 0x89 && *(p + 1) == 0xdc)
+ return true;
+ return false;
+}
+
// subq $0x20, %rsp
bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) {
uint8_t *p = m_cur_insn;
@@ -476,6 +517,46 @@ bool x86AssemblyInspectionEngine::lea_rbp_rsp_pattern_p(int &amount) {
return false;
}
+// lea -0x28(%ebx), %esp
+// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
+bool x86AssemblyInspectionEngine::lea_rbx_rsp_pattern_p(int &amount) {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+
+ // Check opcode
+ if (*p != 0x8d)
+ return false;
+ ++p;
+
+ // 8 bit displacement
+ if (*p == 0x63) {
+ amount = (int8_t)p[1];
+ return true;
+ }
+
+ // 32 bit displacement
+ if (*p == 0xa3) {
+ amount = (int32_t)extract_4(p + 1);
+ return true;
+ }
+
+ return false;
+}
+
+// and -0xfffffff0, %esp
+// (32-bit and 64-bit variants, 8-bit and 32-bit displacement)
+bool x86AssemblyInspectionEngine::and_rsp_pattern_p() {
+ uint8_t *p = m_cur_insn;
+ if (m_wordsize == 8 && *p == 0x48)
+ p++;
+
+ if (*p != 0x81 && *p != 0x83)
+ return false;
+
+ return *++p == 0xe4;
+}
+
// popq %rbx
// popl %ebx
bool x86AssemblyInspectionEngine::pop_reg_p(int &regno) {
@@ -588,9 +669,7 @@ bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p(
// ret [0xc9] or [0xc2 imm8] or [0xca imm8]
bool x86AssemblyInspectionEngine::ret_pattern_p() {
uint8_t *p = m_cur_insn;
- if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3)
- return true;
- return false;
+ return *p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3;
}
uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) {
@@ -636,11 +715,12 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
if (data == nullptr || size == 0)
return false;
- if (m_register_map_initialized == false)
+ if (!m_register_map_initialized)
return false;
addr_t current_func_text_offset = 0;
- int current_sp_bytes_offset_from_cfa = 0;
+ int current_sp_bytes_offset_from_fa = 0;
+ bool is_aligned = false;
UnwindPlan::Row::RegisterLocation initial_regloc;
UnwindPlan::RowSP row(new UnwindPlan::Row);
@@ -657,8 +737,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc);
// saved instruction pointer can be found at CFA - wordsize.
- current_sp_bytes_offset_from_cfa = m_wordsize;
- initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa = m_wordsize;
+ initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa);
row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc);
unwind_plan.AppendRow(row);
@@ -682,6 +762,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI
int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the
// epilogue started executed
+ bool prologue_completed_is_aligned;
std::vector<bool> prologue_completed_saved_registers;
while (current_func_text_offset < size) {
@@ -701,22 +782,59 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
break;
}
- if (push_rbp_pattern_p()) {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
- UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset());
- row->SetRegisterInfo(m_lldb_fp_regnum, regloc);
- saved_registers[m_machine_fp_regnum] = true;
- row_updated = true;
+ auto &cfa_value = row->GetCFAValue();
+ auto &afa_value = row->GetAFAValue();
+ auto fa_value_ptr = is_aligned ? &afa_value : &cfa_value;
+
+ if (mov_rsp_rbp_pattern_p()) {
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_fp_regnum, fa_value_ptr->GetOffset());
+ row_updated = true;
+ }
+ }
+
+ else if (mov_rsp_rbx_pattern_p()) {
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_alt_fp_regnum, fa_value_ptr->GetOffset());
+ row_updated = true;
+ }
}
- else if (mov_rsp_rbp_pattern_p()) {
- row->GetCFAValue().SetIsRegisterPlusOffset(
- m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
+ else if (and_rsp_pattern_p()) {
+ current_sp_bytes_offset_from_fa = 0;
+ afa_value.SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);
+ fa_value_ptr = &afa_value;
+ is_aligned = true;
row_updated = true;
}
+ else if (mov_rbp_rsp_pattern_p()) {
+ if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum)
+ {
+ is_aligned = false;
+ fa_value_ptr = &cfa_value;
+ afa_value.SetUnspecified();
+ row_updated = true;
+ }
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum)
+ current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
+ }
+
+ else if (mov_rbx_rsp_pattern_p()) {
+ if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum)
+ {
+ is_aligned = false;
+ fa_value_ptr = &cfa_value;
+ afa_value.SetUnspecified();
+ row_updated = true;
+ }
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum)
+ current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
+ }
+
// This is the start() function (or a pthread equivalent), it starts with a
// pushl $0x0 which puts the saved pc value of 0 on the stack. In this
// case we want to pretend we didn't see a stack movement at all --
@@ -726,21 +844,24 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
else if (push_reg_p(machine_regno)) {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- // the PUSH instruction has moved the stack pointer - if the CFA is set
+ current_sp_bytes_offset_from_fa += m_wordsize;
+ // the PUSH instruction has moved the stack pointer - if the FA is set
// in terms of the stack pointer, we need to add a new row of
// instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
// record where non-volatile (callee-saved, spilled) registers are saved
// on the stack
if (nonvolatile_reg_p(machine_regno) &&
machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
- saved_registers[machine_regno] == false) {
+ !saved_registers[machine_regno]) {
UnwindPlan::Row::RegisterLocation regloc;
- regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa);
+ if (is_aligned)
+ regloc.SetAtAFAPlusOffset(-current_sp_bytes_offset_from_fa);
+ else
+ regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa);
row->SetRegisterInfo(lldb_regno, regloc);
saved_registers[machine_regno] = true;
row_updated = true;
@@ -748,37 +869,37 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
else if (pop_reg_p(machine_regno)) {
- current_sp_bytes_offset_from_cfa -= m_wordsize;
+ current_sp_bytes_offset_from_fa -= m_wordsize;
if (nonvolatile_reg_p(machine_regno) &&
machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
- saved_registers[machine_regno] == true) {
+ saved_registers[machine_regno]) {
saved_registers[machine_regno] = false;
row->RemoveRegisterInfo(lldb_regno);
- if (machine_regno == (int)m_machine_fp_regnum) {
- row->GetCFAValue().SetIsRegisterPlusOffset(
- m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
+ if (lldb_regno == fa_value_ptr->GetRegisterNumber()) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, fa_value_ptr->GetOffset());
}
in_epilogue = true;
row_updated = true;
}
- // the POP instruction has moved the stack pointer - if the CFA is set in
+ // the POP instruction has moved the stack pointer - if the FA is set in
// terms of the stack pointer, we need to add a new row of instructions.
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetIsRegisterPlusOffset(
- m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);
row_updated = true;
}
}
else if (pop_misc_reg_p()) {
- current_sp_bytes_offset_from_cfa -= m_wordsize;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetIsRegisterPlusOffset(
- m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa -= m_wordsize;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);
row_updated = true;
}
}
@@ -787,41 +908,57 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
// off the stack into rbp (restoring the caller's rbp value). It is the
// opposite of ENTER, or 'push rbp, mov rsp rbp'.
else if (leave_pattern_p()) {
- // We're going to copy the value in rbp into rsp, so re-set the sp offset
- // based on the CFAValue. Also, adjust it to recognize that we're
- // popping the saved rbp value off the stack.
- current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset();
- current_sp_bytes_offset_from_cfa -= m_wordsize;
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
-
- // rbp is restored to the caller's value
- saved_registers[m_machine_fp_regnum] = false;
- row->RemoveRegisterInfo(m_lldb_fp_regnum);
-
- // cfa is now in terms of rsp again.
- row->GetCFAValue().SetIsRegisterPlusOffset(
- m_lldb_sp_regnum, row->GetCFAValue().GetOffset());
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ if (saved_registers[m_machine_fp_regnum]) {
+ saved_registers[m_machine_fp_regnum] = false;
+ row->RemoveRegisterInfo(m_lldb_fp_regnum);
+
+ row_updated = true;
+ }
+
+ if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum)
+ {
+ is_aligned = false;
+ fa_value_ptr = &cfa_value;
+ afa_value.SetUnspecified();
+ row_updated = true;
+ }
+
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum)
+ {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, fa_value_ptr->GetOffset());
+
+ current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset();
+ }
+
+ current_sp_bytes_offset_from_fa -= m_wordsize;
+
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetIsRegisterPlusOffset(
+ m_lldb_sp_regnum, current_sp_bytes_offset_from_fa);
+ row_updated = true;
+ }
in_epilogue = true;
- row_updated = true;
}
else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) &&
nonvolatile_reg_p(machine_regno) &&
machine_regno_to_lldb_regno(machine_regno, lldb_regno) &&
- saved_registers[machine_regno] == false) {
+ !saved_registers[machine_regno]) {
saved_registers[machine_regno] = true;
UnwindPlan::Row::RegisterLocation regloc;
// stack_offset for 'movq %r15, -80(%rbp)' will be 80. In the Row, we
- // want to express this as the offset from the CFA. If the frame base is
- // rbp (like the above instruction), the CFA offset for rbp is probably
- // 16. So we want to say that the value is stored at the CFA address -
+ // want to express this as the offset from the FA. If the frame base is
+ // rbp (like the above instruction), the FA offset for rbp is probably
+ // 16. So we want to say that the value is stored at the FA address -
// 96.
- regloc.SetAtCFAPlusOffset(
- -(stack_offset + row->GetCFAValue().GetOffset()));
+ if (is_aligned)
+ regloc.SetAtAFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset()));
+ else
+ regloc.SetAtCFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset()));
row->SetRegisterInfo(lldb_regno, regloc);
@@ -829,17 +966,17 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
else if (sub_rsp_pattern_p(stack_offset)) {
- current_sp_bytes_offset_from_cfa += stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa += stack_offset;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
}
else if (add_rsp_pattern_p(stack_offset)) {
- current_sp_bytes_offset_from_cfa -= stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa -= stack_offset;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
in_epilogue = true;
@@ -847,27 +984,48 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
else if (push_extended_pattern_p() || push_imm_pattern_p() ||
push_misc_reg_p()) {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa += m_wordsize;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
}
else if (lea_rsp_pattern_p(stack_offset)) {
- current_sp_bytes_offset_from_cfa -= stack_offset;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa -= stack_offset;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
if (stack_offset > 0)
in_epilogue = true;
}
- else if (lea_rbp_rsp_pattern_p(stack_offset) &&
- row->GetCFAValue().GetRegisterNumber() == m_lldb_fp_regnum) {
- current_sp_bytes_offset_from_cfa =
- row->GetCFAValue().GetOffset() - stack_offset;
+ else if (lea_rbp_rsp_pattern_p(stack_offset)) {
+ if (is_aligned &&
+ cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) {
+ is_aligned = false;
+ fa_value_ptr = &cfa_value;
+ afa_value.SetUnspecified();
+ row_updated = true;
+ }
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) {
+ current_sp_bytes_offset_from_fa =
+ fa_value_ptr->GetOffset() - stack_offset;
+ }
+ }
+
+ else if (lea_rbx_rsp_pattern_p(stack_offset)) {
+ if (is_aligned &&
+ cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum) {
+ is_aligned = false;
+ fa_value_ptr = &cfa_value;
+ afa_value.SetUnspecified();
+ row_updated = true;
+ }
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum) {
+ current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset() - stack_offset;
+ }
}
else if (ret_pattern_p() && prologue_completed_row.get()) {
@@ -877,8 +1035,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *prologue_completed_row.get();
row.reset(newrow);
- current_sp_bytes_offset_from_cfa =
+ current_sp_bytes_offset_from_fa =
prologue_completed_sp_bytes_offset_from_cfa;
+ is_aligned = prologue_completed_is_aligned;
saved_registers.clear();
saved_registers.resize(prologue_completed_saved_registers.size(), false);
@@ -896,9 +1055,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
// This is used in i386 programs to get the PIC base address for finding
// global data
else if (call_next_insn_pattern_p()) {
- current_sp_bytes_offset_from_cfa += m_wordsize;
- if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) {
- row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa);
+ current_sp_bytes_offset_from_fa += m_wordsize;
+ if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) {
+ fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa);
row_updated = true;
}
}
@@ -914,7 +1073,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
}
}
- if (in_epilogue == false && row_updated) {
+ if (!in_epilogue && row_updated) {
// If we're not in an epilogue sequence, save the updated Row
UnwindPlan::Row *newrow = new UnwindPlan::Row;
*newrow = *row.get();
@@ -929,9 +1088,10 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
// We may change the sp value without adding a new Row necessarily -- keep
// track of it either way.
- if (in_epilogue == false) {
+ if (!in_epilogue) {
prologue_completed_sp_bytes_offset_from_cfa =
- current_sp_bytes_offset_from_cfa;
+ current_sp_bytes_offset_from_fa;
+ prologue_completed_is_aligned = is_aligned;
}
m_cur_insn = m_cur_insn + insn_len;
@@ -1194,7 +1354,7 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
uint8_t *data, size_t size, size_t &offset) {
offset = 0;
- if (m_register_map_initialized == false)
+ if (!m_register_map_initialized)
return false;
while (offset < size) {
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index cec9803c8a49..e02b510ba1f9 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -98,10 +98,15 @@ private:
bool push_extended_pattern_p();
bool push_misc_reg_p();
bool mov_rsp_rbp_pattern_p();
+ bool mov_rsp_rbx_pattern_p();
+ bool mov_rbp_rsp_pattern_p();
+ bool mov_rbx_rsp_pattern_p();
bool sub_rsp_pattern_p(int &amount);
bool add_rsp_pattern_p(int &amount);
bool lea_rsp_pattern_p(int &amount);
bool lea_rbp_rsp_pattern_p(int &amount);
+ bool lea_rbx_rsp_pattern_p(int &amount);
+ bool and_rsp_pattern_p();
bool push_reg_p(int &regno);
bool pop_reg_p(int &regno);
bool pop_rbp_pattern_p();
@@ -157,9 +162,11 @@ private:
uint32_t m_machine_ip_regnum;
uint32_t m_machine_sp_regnum;
uint32_t m_machine_fp_regnum;
+ uint32_t m_machine_alt_fp_regnum;
uint32_t m_lldb_ip_regnum;
uint32_t m_lldb_sp_regnum;
uint32_t m_lldb_fp_regnum;
+ uint32_t m_lldb_alt_fp_regnum;
typedef std::map<uint32_t, lldb_reg_info> MachineRegnumToNameAndLLDBRegnum;